Refactor: remove monolithic configuration class
This commit is contained in:
@@ -127,7 +127,7 @@ Configuration from_path(std::string_view path, std::string_view resourceDirector
|
||||
if (file.is_open())
|
||||
{
|
||||
json_t simulation = json_t::parse(file, parser_callback, true, true).at(Configuration::KEY);
|
||||
return simulation.get<DRAMSys::Config::Configuration>();
|
||||
return simulation.get<Config::Configuration>();
|
||||
}
|
||||
throw std::runtime_error("Failed to open file " + std::string(path));
|
||||
}
|
||||
|
||||
@@ -47,15 +47,13 @@ enum class StoreModeType
|
||||
{
|
||||
NoStorage,
|
||||
Store,
|
||||
ErrorModel,
|
||||
Invalid = -1
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(StoreModeType,
|
||||
{{StoreModeType::Invalid, nullptr},
|
||||
{StoreModeType::NoStorage, "NoStorage"},
|
||||
{StoreModeType::Store, "Store"},
|
||||
{StoreModeType::ErrorModel, "ErrorModel"}})
|
||||
{StoreModeType::Store, "Store"}})
|
||||
|
||||
struct SimConfig
|
||||
{
|
||||
@@ -67,8 +65,6 @@ struct SimConfig
|
||||
std::optional<bool> DatabaseRecording;
|
||||
std::optional<bool> Debug;
|
||||
std::optional<bool> EnableWindowing;
|
||||
std::optional<std::string> ErrorCSVFile;
|
||||
std::optional<unsigned int> ErrorChipSeed;
|
||||
std::optional<bool> PowerAnalysis;
|
||||
std::optional<std::string> SimulationName;
|
||||
std::optional<bool> SimulationProgressBar;
|
||||
@@ -84,8 +80,6 @@ NLOHMANN_JSONIFY_ALL_THINGS(SimConfig,
|
||||
DatabaseRecording,
|
||||
Debug,
|
||||
EnableWindowing,
|
||||
ErrorCSVFile,
|
||||
ErrorChipSeed,
|
||||
PowerAnalysis,
|
||||
SimulationName,
|
||||
SimulationProgressBar,
|
||||
|
||||
@@ -46,6 +46,40 @@
|
||||
namespace DRAMSys::Config
|
||||
{
|
||||
|
||||
enum class MemoryType
|
||||
{
|
||||
DDR3,
|
||||
DDR4,
|
||||
DDR5,
|
||||
LPDDR4,
|
||||
LPDDR5,
|
||||
WideIO,
|
||||
WideIO2,
|
||||
GDDR5,
|
||||
GDDR5X,
|
||||
GDDR6,
|
||||
HBM2,
|
||||
HBM3,
|
||||
STTMRAM,
|
||||
Invalid = -1
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(MemoryType,
|
||||
{{MemoryType::Invalid, nullptr},
|
||||
{MemoryType::DDR3, "DDR3"},
|
||||
{MemoryType::DDR4, "DDR4"},
|
||||
{MemoryType::DDR5, "DDR5"},
|
||||
{MemoryType::LPDDR4, "LPDDR4"},
|
||||
{MemoryType::LPDDR5, "LPDDR5"},
|
||||
{MemoryType::WideIO, "WIDEIO_SDR"},
|
||||
{MemoryType::WideIO2, "WIDEIO2"},
|
||||
{MemoryType::GDDR5, "GDDR5"},
|
||||
{MemoryType::GDDR5X, "GDDR5X"},
|
||||
{MemoryType::GDDR6, "GDDR6"},
|
||||
{MemoryType::HBM2, "HBM2"},
|
||||
{MemoryType::HBM3, "HBM3"},
|
||||
{MemoryType::STTMRAM, "STTMRAM"}})
|
||||
|
||||
struct MemSpec
|
||||
{
|
||||
static constexpr std::string_view KEY = "memspec";
|
||||
@@ -53,7 +87,7 @@ struct MemSpec
|
||||
|
||||
MemArchitectureSpecType memarchitecturespec;
|
||||
std::string memoryId;
|
||||
std::string memoryType;
|
||||
MemoryType memoryType;
|
||||
MemTimingSpecType memtimingspec;
|
||||
std::optional<MemPowerSpec> mempowerspec;
|
||||
};
|
||||
|
||||
@@ -36,9 +36,10 @@
|
||||
|
||||
#include "DebugManager.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#include <iostream>
|
||||
#include <systemc>
|
||||
|
||||
#include <DRAMSys/configuration/Configuration.h>
|
||||
#ifndef NDEBUG
|
||||
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
@@ -53,14 +53,17 @@ namespace DRAMSys
|
||||
{
|
||||
|
||||
TlmRecorder::TlmRecorder(const std::string& name,
|
||||
const Configuration& config,
|
||||
const SimConfig& simConfig,
|
||||
const McConfig& mcConfig,
|
||||
const MemSpec& memSpec,
|
||||
const std::string& dbName,
|
||||
std::string mcconfig,
|
||||
std::string memspec,
|
||||
std::string traces) :
|
||||
const std::string& mcConfigString,
|
||||
const std::string& memSpecString,
|
||||
const std::string& traces) :
|
||||
name(name),
|
||||
config(config),
|
||||
memSpec(*config.memSpec),
|
||||
simConfig(simConfig),
|
||||
mcConfig(mcConfig),
|
||||
memSpec(memSpec),
|
||||
currentDataBuffer(&recordingDataBuffer.at(0)),
|
||||
storageDataBuffer(&recordingDataBuffer.at(1)),
|
||||
simulationTimeCoveredByRecording(SC_ZERO_TIME)
|
||||
@@ -79,7 +82,7 @@ TlmRecorder::TlmRecorder(const std::string& name,
|
||||
executeInitialSqlCommand();
|
||||
prepareSqlStatements();
|
||||
|
||||
insertGeneralInfo(mcconfig, memspec, traces);
|
||||
insertGeneralInfo(mcConfigString, memSpecString, traces);
|
||||
insertCommandLengths();
|
||||
|
||||
PRINTDEBUGMESSAGE(name, "Starting new database transaction");
|
||||
@@ -435,52 +438,54 @@ void TlmRecorder::insertDebugMessageInDB(const std::string& message, const sc_ti
|
||||
executeSqlStatement(insertDebugMessageStatement);
|
||||
}
|
||||
|
||||
void TlmRecorder::insertGeneralInfo(std::string mcconfig, std::string memspec, std::string traces)
|
||||
void TlmRecorder::insertGeneralInfo(const std::string& mcConfigString,
|
||||
const std::string& memSpecString,
|
||||
const std::string& traces)
|
||||
{
|
||||
sqlite3_bind_int(
|
||||
insertGeneralInfoStatement, 1, static_cast<int>(config.memSpec->ranksPerChannel));
|
||||
sqlite3_bind_int(
|
||||
insertGeneralInfoStatement, 2, static_cast<int>(config.memSpec->bankGroupsPerChannel));
|
||||
sqlite3_bind_int(
|
||||
insertGeneralInfoStatement, 3, static_cast<int>(config.memSpec->banksPerChannel));
|
||||
sqlite3_bind_int64(
|
||||
insertGeneralInfoStatement, 4, static_cast<int64_t>(config.memSpec->tCK.value()));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 1, static_cast<int>(memSpec.ranksPerChannel));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 2, static_cast<int>(memSpec.bankGroupsPerChannel));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 3, static_cast<int>(memSpec.banksPerChannel));
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 4, static_cast<int64_t>(memSpec.tCK.value()));
|
||||
sqlite3_bind_text(insertGeneralInfoStatement, 5, "PS", 2, nullptr);
|
||||
|
||||
sqlite3_bind_text(insertGeneralInfoStatement,
|
||||
6,
|
||||
mcconfig.c_str(),
|
||||
static_cast<int>(mcconfig.length()),
|
||||
mcConfigString.c_str(),
|
||||
static_cast<int>(mcConfigString.length()),
|
||||
nullptr);
|
||||
sqlite3_bind_text(insertGeneralInfoStatement,
|
||||
7,
|
||||
memspec.c_str(),
|
||||
static_cast<int>(memspec.length()),
|
||||
memSpecString.c_str(),
|
||||
static_cast<int>(memSpecString.length()),
|
||||
nullptr);
|
||||
sqlite3_bind_text(
|
||||
insertGeneralInfoStatement, 8, traces.c_str(), static_cast<int>(traces.length()), nullptr);
|
||||
if (config.enableWindowing)
|
||||
|
||||
if (simConfig.enableWindowing)
|
||||
{
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement,
|
||||
9,
|
||||
static_cast<int64_t>((config.memSpec->tCK * config.windowSize).value()));
|
||||
static_cast<int64_t>((memSpec.tCK * simConfig.windowSize).value()));
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlite3_bind_int64(insertGeneralInfoStatement, 9, 0);
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 10, static_cast<int>(config.refreshMaxPostponed));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 11, static_cast<int>(config.refreshMaxPulledin));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 12, static_cast<int>(UINT_MAX));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 13, static_cast<int>(config.requestBufferSize));
|
||||
}
|
||||
sqlite3_bind_int(
|
||||
insertGeneralInfoStatement, 14, static_cast<int>(config.memSpec->getPer2BankOffset()));
|
||||
insertGeneralInfoStatement, 10, static_cast<int>(mcConfig.refreshMaxPostponed));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 11, static_cast<int>(mcConfig.refreshMaxPulledin));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 12, static_cast<int>(UINT_MAX));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 13, static_cast<int>(mcConfig.requestBufferSize));
|
||||
sqlite3_bind_int(insertGeneralInfoStatement, 14, static_cast<int>(memSpec.getPer2BankOffset()));
|
||||
|
||||
const MemSpec& memSpec = *config.memSpec;
|
||||
const auto memoryType = memSpec.memoryType;
|
||||
|
||||
bool rowColumnCommandBus =
|
||||
(memoryType == MemSpec::MemoryType::HBM2) || (memoryType == MemSpec::MemoryType::HBM3);
|
||||
(memoryType == Config::MemoryType::HBM2) || (memoryType == Config::MemoryType::HBM3);
|
||||
|
||||
bool pseudoChannelMode = [&memSpec, memoryType]() -> bool
|
||||
bool pseudoChannelMode = [this, memoryType]() -> bool
|
||||
{
|
||||
if (memoryType != MemSpec::MemoryType::HBM2 && memoryType != MemSpec::MemoryType::HBM3)
|
||||
if (memoryType != Config::MemoryType::HBM2 && memoryType != Config::MemoryType::HBM3)
|
||||
return false;
|
||||
|
||||
return memSpec.pseudoChannelsPerChannel != 1;
|
||||
@@ -493,16 +498,14 @@ void TlmRecorder::insertGeneralInfo(std::string mcconfig, std::string memspec, s
|
||||
|
||||
void TlmRecorder::insertCommandLengths()
|
||||
{
|
||||
const MemSpec& _memSpec = *config.memSpec;
|
||||
|
||||
auto insertCommandLength = [this, &_memSpec](Command command)
|
||||
auto insertCommandLength = [this](Command command)
|
||||
{
|
||||
auto commandName = command.toString();
|
||||
|
||||
sqlite3_bind_text(
|
||||
insertCommandLengthsStatement, 1, commandName.c_str(), commandName.length(), nullptr);
|
||||
sqlite3_bind_double(
|
||||
insertCommandLengthsStatement, 2, _memSpec.getCommandLengthInCycles(command));
|
||||
insertCommandLengthsStatement, 2, memSpec.getCommandLengthInCycles(command));
|
||||
executeSqlStatement(insertCommandLengthsStatement);
|
||||
};
|
||||
|
||||
|
||||
@@ -43,7 +43,9 @@
|
||||
|
||||
#include "DRAMSys/common/dramExtensions.h"
|
||||
#include "DRAMSys/common/utils.h"
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpec.h"
|
||||
#include "DRAMSys/controller/McConfig.h"
|
||||
#include "DRAMSys/simulation/SimConfig.h"
|
||||
|
||||
#include <string>
|
||||
#include <systemc>
|
||||
@@ -63,11 +65,13 @@ class TlmRecorder
|
||||
{
|
||||
public:
|
||||
TlmRecorder(const std::string& name,
|
||||
const Configuration& config,
|
||||
const SimConfig& simConfig,
|
||||
const McConfig& mcConfig,
|
||||
const MemSpec& memSpec,
|
||||
const std::string& dbName,
|
||||
std::string mcconfig,
|
||||
std::string memspec,
|
||||
std::string traces);
|
||||
const std::string& mcconfig,
|
||||
const std::string& memspec,
|
||||
const std::string& traces);
|
||||
TlmRecorder(const TlmRecorder&) = delete;
|
||||
TlmRecorder(TlmRecorder&&) = default;
|
||||
TlmRecorder& operator=(const TlmRecorder&) = delete;
|
||||
@@ -85,7 +89,8 @@ public:
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
const Configuration& config;
|
||||
const SimConfig& simConfig;
|
||||
const McConfig& mcConfig;
|
||||
const MemSpec& memSpec;
|
||||
|
||||
struct Transaction
|
||||
@@ -168,7 +173,9 @@ private:
|
||||
|
||||
void terminateRemainingTransactions();
|
||||
void commitRecordedDataToDB();
|
||||
void insertGeneralInfo(std::string mcconfig, std::string memspec, std::string traces);
|
||||
void insertGeneralInfo(const std::string& mcConfigString,
|
||||
const std::string& memSpecString,
|
||||
const std::string& traces);
|
||||
void insertCommandLengths();
|
||||
void insertTransactionInDB(const Transaction& recordingData);
|
||||
void insertRangeInDB(uint64_t id, const sc_core::sc_time& begin, const sc_core::sc_time& end);
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
*/
|
||||
|
||||
#include "dramExtensions.h"
|
||||
#include <DRAMSys/configuration/Configuration.h>
|
||||
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
|
||||
@@ -1,378 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Matthias Jung
|
||||
* Éder F. Zulian
|
||||
* Felipe S. Prado
|
||||
* Lukas Steiner
|
||||
* Luiza Correa
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include "Configuration.h"
|
||||
|
||||
#include "DRAMSys/configuration/memspec/MemSpecDDR3.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecDDR4.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecGDDR5.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecGDDR5X.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecGDDR6.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecHBM2.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecLPDDR4.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecSTTMRAM.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecWideIO.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecWideIO2.h"
|
||||
|
||||
#ifdef DDR5_SIM
|
||||
#include "DRAMSys/configuration/memspec/MemSpecDDR5.h"
|
||||
#endif
|
||||
#ifdef LPDDR5_SIM
|
||||
#include "DRAMSys/configuration/memspec/MemSpecLPDDR5.h"
|
||||
#endif
|
||||
#ifdef HBM3_SIM
|
||||
#include "DRAMSys/configuration/memspec/MemSpecHBM3.h"
|
||||
#endif
|
||||
|
||||
using namespace sc_core;
|
||||
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
enum sc_time_unit string2TimeUnit(const std::string& s)
|
||||
{
|
||||
if (s == "s")
|
||||
return SC_SEC;
|
||||
|
||||
if (s == "ms")
|
||||
return SC_MS;
|
||||
|
||||
if (s == "us")
|
||||
return SC_US;
|
||||
|
||||
if (s == "ns")
|
||||
return SC_NS;
|
||||
|
||||
if (s == "ps")
|
||||
return SC_PS;
|
||||
|
||||
if (s == "fs")
|
||||
return SC_FS;
|
||||
|
||||
SC_REPORT_FATAL("Configuration", ("Could not convert to enum sc_time_unit: " + s).c_str());
|
||||
throw;
|
||||
}
|
||||
|
||||
void Configuration::loadSimConfig(const DRAMSys::Config::SimConfig& simConfig)
|
||||
{
|
||||
addressOffset = simConfig.AddressOffset.value_or(addressOffset);
|
||||
checkTLM2Protocol = simConfig.CheckTLM2Protocol.value_or(checkTLM2Protocol);
|
||||
databaseRecording = simConfig.DatabaseRecording.value_or(databaseRecording);
|
||||
debug = simConfig.Debug.value_or(debug);
|
||||
enableWindowing = simConfig.EnableWindowing.value_or(enableWindowing);
|
||||
simulationName = simConfig.SimulationName.value_or(simulationName);
|
||||
simulationProgressBar = simConfig.SimulationProgressBar.value_or(simulationProgressBar);
|
||||
useMalloc = simConfig.UseMalloc.value_or(useMalloc);
|
||||
|
||||
if (const auto& _storeMode = simConfig.StoreMode)
|
||||
storeMode = [=]
|
||||
{
|
||||
switch (*_storeMode)
|
||||
{
|
||||
case DRAMSys::Config::StoreModeType::NoStorage:
|
||||
return StoreMode::NoStorage;
|
||||
case DRAMSys::Config::StoreModeType::Store:
|
||||
return StoreMode::Store;
|
||||
default:
|
||||
SC_REPORT_FATAL("Configuration", "Invalid StoreMode");
|
||||
return StoreMode::NoStorage; // Silence Warning
|
||||
}
|
||||
}();
|
||||
|
||||
windowSize = simConfig.WindowSize.value_or(windowSize);
|
||||
if (windowSize == 0)
|
||||
SC_REPORT_FATAL("Configuration", "Minimum window size is 1");
|
||||
|
||||
powerAnalysis = simConfig.PowerAnalysis.value_or(powerAnalysis);
|
||||
#ifndef DRAMPOWER
|
||||
if (powerAnalysis)
|
||||
SC_REPORT_FATAL("Configuration",
|
||||
"Power analysis is only supported with included DRAMPower library!");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Configuration::loadMCConfig(const DRAMSys::Config::McConfig& mcConfig)
|
||||
{
|
||||
if (const auto& _pagePolicy = mcConfig.PagePolicy)
|
||||
pagePolicy = [=]
|
||||
{
|
||||
switch (*_pagePolicy)
|
||||
{
|
||||
case DRAMSys::Config::PagePolicyType::Open:
|
||||
return PagePolicy::Open;
|
||||
case DRAMSys::Config::PagePolicyType::OpenAdaptive:
|
||||
return PagePolicy::OpenAdaptive;
|
||||
case DRAMSys::Config::PagePolicyType::Closed:
|
||||
return PagePolicy::Closed;
|
||||
case DRAMSys::Config::PagePolicyType::ClosedAdaptive:
|
||||
return PagePolicy::ClosedAdaptive;
|
||||
default:
|
||||
SC_REPORT_FATAL("Configuration", "Invalid PagePolicy");
|
||||
return PagePolicy::Open; // Silence Warning
|
||||
}
|
||||
}();
|
||||
|
||||
if (const auto& _scheduler = mcConfig.Scheduler)
|
||||
scheduler = [=]
|
||||
{
|
||||
switch (*_scheduler)
|
||||
{
|
||||
case DRAMSys::Config::SchedulerType::Fifo:
|
||||
return Scheduler::Fifo;
|
||||
case DRAMSys::Config::SchedulerType::FrFcfs:
|
||||
return Scheduler::FrFcfs;
|
||||
case DRAMSys::Config::SchedulerType::FrFcfsGrp:
|
||||
return Scheduler::FrFcfsGrp;
|
||||
case DRAMSys::Config::SchedulerType::GrpFrFcfs:
|
||||
return Scheduler::GrpFrFcfs;
|
||||
case DRAMSys::Config::SchedulerType::GrpFrFcfsWm:
|
||||
return Scheduler::GrpFrFcfsWm;
|
||||
default:
|
||||
SC_REPORT_FATAL("Configuration", "Invalid Scheduler");
|
||||
return Scheduler::Fifo; // Silence Warning
|
||||
}
|
||||
}();
|
||||
|
||||
if (const auto& _schedulerBuffer = mcConfig.SchedulerBuffer)
|
||||
schedulerBuffer = [=]
|
||||
{
|
||||
switch (*_schedulerBuffer)
|
||||
{
|
||||
case DRAMSys::Config::SchedulerBufferType::Bankwise:
|
||||
return SchedulerBuffer::Bankwise;
|
||||
case DRAMSys::Config::SchedulerBufferType::ReadWrite:
|
||||
return SchedulerBuffer::ReadWrite;
|
||||
case DRAMSys::Config::SchedulerBufferType::Shared:
|
||||
return SchedulerBuffer::Shared;
|
||||
default:
|
||||
SC_REPORT_FATAL("Configuration", "Invalid SchedulerBuffer");
|
||||
return SchedulerBuffer::Bankwise; // Silence Warning
|
||||
}
|
||||
}();
|
||||
|
||||
if (const auto& _cmdMux = mcConfig.CmdMux)
|
||||
cmdMux = [=]
|
||||
{
|
||||
switch (*_cmdMux)
|
||||
{
|
||||
case DRAMSys::Config::CmdMuxType::Oldest:
|
||||
return CmdMux::Oldest;
|
||||
case DRAMSys::Config::CmdMuxType::Strict:
|
||||
return CmdMux::Strict;
|
||||
default:
|
||||
SC_REPORT_FATAL("Configuration", "Invalid CmdMux");
|
||||
return CmdMux::Oldest; // Silence Warning
|
||||
}
|
||||
}();
|
||||
|
||||
if (const auto& _respQueue = mcConfig.RespQueue)
|
||||
respQueue = [=]
|
||||
{
|
||||
switch (*_respQueue)
|
||||
{
|
||||
case DRAMSys::Config::RespQueueType::Fifo:
|
||||
return RespQueue::Fifo;
|
||||
case DRAMSys::Config::RespQueueType::Reorder:
|
||||
return RespQueue::Reorder;
|
||||
default:
|
||||
SC_REPORT_FATAL("Configuration", "Invalid RespQueue");
|
||||
return RespQueue::Fifo; // Silence Warning
|
||||
}
|
||||
}();
|
||||
|
||||
if (const auto& _refreshPolicy = mcConfig.RefreshPolicy)
|
||||
refreshPolicy = [=]
|
||||
{
|
||||
switch (*_refreshPolicy)
|
||||
{
|
||||
case DRAMSys::Config::RefreshPolicyType::NoRefresh:
|
||||
return RefreshPolicy::NoRefresh;
|
||||
case DRAMSys::Config::RefreshPolicyType::AllBank:
|
||||
return RefreshPolicy::AllBank;
|
||||
case DRAMSys::Config::RefreshPolicyType::PerBank:
|
||||
return RefreshPolicy::PerBank;
|
||||
case DRAMSys::Config::RefreshPolicyType::Per2Bank:
|
||||
return RefreshPolicy::Per2Bank;
|
||||
case DRAMSys::Config::RefreshPolicyType::SameBank:
|
||||
return RefreshPolicy::SameBank;
|
||||
default:
|
||||
SC_REPORT_FATAL("Configuration", "Invalid RefreshPolicy");
|
||||
return RefreshPolicy::NoRefresh; // Silence Warning
|
||||
}
|
||||
}();
|
||||
|
||||
if (const auto& _powerDownPolicy = mcConfig.PowerDownPolicy)
|
||||
powerDownPolicy = [=]
|
||||
{
|
||||
switch (*_powerDownPolicy)
|
||||
{
|
||||
case DRAMSys::Config::PowerDownPolicyType::NoPowerDown:
|
||||
return PowerDownPolicy::NoPowerDown;
|
||||
case DRAMSys::Config::PowerDownPolicyType::Staggered:
|
||||
return PowerDownPolicy::Staggered;
|
||||
default:
|
||||
SC_REPORT_FATAL("Configuration", "Invalid PowerDownPolicy");
|
||||
return PowerDownPolicy::NoPowerDown; // Silence Warning
|
||||
}
|
||||
}();
|
||||
|
||||
if (const auto& _arbiter = mcConfig.Arbiter)
|
||||
arbiter = [=]
|
||||
{
|
||||
switch (*_arbiter)
|
||||
{
|
||||
case DRAMSys::Config::ArbiterType::Simple:
|
||||
return Arbiter::Simple;
|
||||
case DRAMSys::Config::ArbiterType::Fifo:
|
||||
return Arbiter::Fifo;
|
||||
case DRAMSys::Config::ArbiterType::Reorder:
|
||||
return Arbiter::Reorder;
|
||||
default:
|
||||
SC_REPORT_FATAL("Configuration", "Invalid Arbiter");
|
||||
return Arbiter::Simple; // Silence Warning
|
||||
}
|
||||
}();
|
||||
|
||||
refreshMaxPostponed = mcConfig.RefreshMaxPostponed.value_or(refreshMaxPostponed);
|
||||
refreshMaxPulledin = mcConfig.RefreshMaxPulledin.value_or(refreshMaxPulledin);
|
||||
highWatermark = mcConfig.HighWatermark.value_or(highWatermark);
|
||||
lowWatermark = mcConfig.LowWatermark.value_or(lowWatermark);
|
||||
maxActiveTransactions = mcConfig.MaxActiveTransactions.value_or(maxActiveTransactions);
|
||||
refreshManagement = mcConfig.RefreshManagement.value_or(refreshManagement);
|
||||
|
||||
requestBufferSize = mcConfig.RequestBufferSize.value_or(requestBufferSize);
|
||||
if (requestBufferSize == 0)
|
||||
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
|
||||
|
||||
requestBufferSizeRead = mcConfig.RequestBufferSizeRead.value_or(requestBufferSizeRead);
|
||||
if (requestBufferSizeRead == 0)
|
||||
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
|
||||
|
||||
requestBufferSizeWrite = mcConfig.RequestBufferSizeWrite.value_or(requestBufferSizeWrite);
|
||||
if (requestBufferSizeWrite == 0)
|
||||
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
|
||||
|
||||
if (const auto& _arbitrationDelayFw = mcConfig.ArbitrationDelayFw)
|
||||
{
|
||||
arbitrationDelayFw =
|
||||
std::round(sc_time(*_arbitrationDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||
}
|
||||
|
||||
if (const auto& _arbitrationDelayBw = mcConfig.ArbitrationDelayBw)
|
||||
{
|
||||
arbitrationDelayBw =
|
||||
std::round(sc_time(*_arbitrationDelayBw, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||
}
|
||||
|
||||
if (const auto& _thinkDelayFw = mcConfig.ThinkDelayFw)
|
||||
{
|
||||
thinkDelayFw = std::round(sc_time(*_thinkDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||
}
|
||||
|
||||
if (const auto& _thinkDelayBw = mcConfig.ThinkDelayBw)
|
||||
{
|
||||
thinkDelayBw = std::round(sc_time(*_thinkDelayBw, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||
}
|
||||
|
||||
if (const auto& _phyDelayFw = mcConfig.PhyDelayFw)
|
||||
{
|
||||
phyDelayFw = std::round(sc_time(*_phyDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||
}
|
||||
|
||||
if (const auto& _phyDelayBw = mcConfig.PhyDelayBw)
|
||||
{
|
||||
phyDelayBw = std::round(sc_time(*_phyDelayBw, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||
}
|
||||
|
||||
{
|
||||
auto _blockingReadDelay = mcConfig.BlockingReadDelay.value_or(60);
|
||||
blockingReadDelay =
|
||||
std::round(sc_time(_blockingReadDelay, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||
}
|
||||
|
||||
{
|
||||
auto _blockingWriteDelay = mcConfig.BlockingWriteDelay.value_or(60);
|
||||
blockingWriteDelay =
|
||||
std::round(sc_time(_blockingWriteDelay, SC_NS) / memSpec->tCK) * memSpec->tCK;
|
||||
}
|
||||
}
|
||||
|
||||
void Configuration::loadMemSpec(const DRAMSys::Config::MemSpec& memSpecConfig)
|
||||
{
|
||||
std::string memoryType = memSpecConfig.memoryType;
|
||||
|
||||
if (memoryType == "DDR3")
|
||||
memSpec = std::make_unique<const MemSpecDDR3>(memSpecConfig);
|
||||
else if (memoryType == "DDR4")
|
||||
memSpec = std::make_unique<const MemSpecDDR4>(memSpecConfig);
|
||||
else if (memoryType == "LPDDR4")
|
||||
memSpec = std::make_unique<const MemSpecLPDDR4>(memSpecConfig);
|
||||
else if (memoryType == "WIDEIO_SDR")
|
||||
memSpec = std::make_unique<const MemSpecWideIO>(memSpecConfig);
|
||||
else if (memoryType == "WIDEIO2")
|
||||
memSpec = std::make_unique<const MemSpecWideIO2>(memSpecConfig);
|
||||
else if (memoryType == "HBM2")
|
||||
memSpec = std::make_unique<const MemSpecHBM2>(memSpecConfig);
|
||||
else if (memoryType == "GDDR5")
|
||||
memSpec = std::make_unique<const MemSpecGDDR5>(memSpecConfig);
|
||||
else if (memoryType == "GDDR5X")
|
||||
memSpec = std::make_unique<const MemSpecGDDR5X>(memSpecConfig);
|
||||
else if (memoryType == "GDDR6")
|
||||
memSpec = std::make_unique<const MemSpecGDDR6>(memSpecConfig);
|
||||
else if (memoryType == "STT-MRAM")
|
||||
memSpec = std::make_unique<const MemSpecSTTMRAM>(memSpecConfig);
|
||||
#ifdef DDR5_SIM
|
||||
else if (memoryType == "DDR5")
|
||||
memSpec = std::make_unique<const MemSpecDDR5>(memSpecConfig);
|
||||
#endif
|
||||
#ifdef LPDDR5_SIM
|
||||
else if (memoryType == "LPDDR5")
|
||||
memSpec = std::make_unique<const MemSpecLPDDR5>(memSpecConfig);
|
||||
#endif
|
||||
#ifdef HBM3_SIM
|
||||
else if (memoryType == "HBM3")
|
||||
memSpec = std::make_unique<const MemSpecHBM3>(memSpecConfig);
|
||||
#endif
|
||||
else
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported DRAM type");
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, RPTU Kaiserslautern-Landau
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Janik Schlemminger
|
||||
* Matthias Jung
|
||||
* Eder F. Zulian
|
||||
* Felipe S. Prado
|
||||
* Lukas Steiner
|
||||
* Luiza Correa
|
||||
* Derek Christ
|
||||
* Thomas Psota
|
||||
*/
|
||||
|
||||
#ifndef CONFIGURATION_H
|
||||
#define CONFIGURATION_H
|
||||
|
||||
#include "DRAMSys/config/DRAMSysConfiguration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpec.h"
|
||||
|
||||
#include <string>
|
||||
#include <systemc>
|
||||
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
class Configuration
|
||||
{
|
||||
public:
|
||||
// MCConfig:
|
||||
enum class PagePolicy
|
||||
{
|
||||
Open,
|
||||
Closed,
|
||||
OpenAdaptive,
|
||||
ClosedAdaptive
|
||||
} pagePolicy = PagePolicy::Open;
|
||||
enum class Scheduler
|
||||
{
|
||||
Fifo,
|
||||
FrFcfs,
|
||||
FrFcfsGrp,
|
||||
GrpFrFcfs,
|
||||
GrpFrFcfsWm
|
||||
} scheduler = Scheduler::FrFcfs;
|
||||
enum class SchedulerBuffer
|
||||
{
|
||||
Bankwise,
|
||||
ReadWrite,
|
||||
Shared
|
||||
} schedulerBuffer = SchedulerBuffer::Bankwise;
|
||||
unsigned int lowWatermark = 0;
|
||||
unsigned int highWatermark = 0;
|
||||
enum class CmdMux
|
||||
{
|
||||
Oldest,
|
||||
Strict
|
||||
} cmdMux = CmdMux::Oldest;
|
||||
enum class RespQueue
|
||||
{
|
||||
Fifo,
|
||||
Reorder
|
||||
} respQueue = RespQueue::Fifo;
|
||||
enum class Arbiter
|
||||
{
|
||||
Simple,
|
||||
Fifo,
|
||||
Reorder
|
||||
} arbiter = Arbiter::Simple;
|
||||
unsigned int requestBufferSize = 8;
|
||||
unsigned int requestBufferSizeRead = 8;
|
||||
unsigned int requestBufferSizeWrite = 8;
|
||||
enum class RefreshPolicy
|
||||
{
|
||||
NoRefresh,
|
||||
PerBank,
|
||||
Per2Bank,
|
||||
SameBank,
|
||||
AllBank
|
||||
} refreshPolicy = RefreshPolicy::AllBank;
|
||||
unsigned int refreshMaxPostponed = 0;
|
||||
unsigned int refreshMaxPulledin = 0;
|
||||
enum class PowerDownPolicy
|
||||
{
|
||||
NoPowerDown,
|
||||
Staggered
|
||||
} powerDownPolicy = PowerDownPolicy::NoPowerDown;
|
||||
unsigned int maxActiveTransactions = 64;
|
||||
bool refreshManagement = false;
|
||||
sc_core::sc_time arbitrationDelayFw = sc_core::SC_ZERO_TIME;
|
||||
sc_core::sc_time arbitrationDelayBw = sc_core::SC_ZERO_TIME;
|
||||
sc_core::sc_time thinkDelayFw = sc_core::SC_ZERO_TIME;
|
||||
sc_core::sc_time thinkDelayBw = sc_core::SC_ZERO_TIME;
|
||||
sc_core::sc_time phyDelayFw = sc_core::SC_ZERO_TIME;
|
||||
sc_core::sc_time phyDelayBw = sc_core::SC_ZERO_TIME;
|
||||
sc_core::sc_time blockingReadDelay = sc_core::SC_ZERO_TIME;
|
||||
sc_core::sc_time blockingWriteDelay = sc_core::SC_ZERO_TIME;
|
||||
|
||||
// SimConfig
|
||||
std::string simulationName = "default";
|
||||
bool databaseRecording = false;
|
||||
bool powerAnalysis = false;
|
||||
bool enableWindowing = false;
|
||||
unsigned int windowSize = 1000;
|
||||
bool debug = false;
|
||||
bool simulationProgressBar = false;
|
||||
bool checkTLM2Protocol = false;
|
||||
bool useMalloc = false;
|
||||
unsigned long long int addressOffset = 0;
|
||||
|
||||
enum class StoreMode
|
||||
{
|
||||
NoStorage,
|
||||
Store
|
||||
} storeMode = StoreMode::NoStorage;
|
||||
|
||||
// MemSpec (from DRAM-Power)
|
||||
std::unique_ptr<const MemSpec> memSpec;
|
||||
|
||||
void loadMCConfig(const DRAMSys::Config::McConfig& mcConfig);
|
||||
void loadSimConfig(const DRAMSys::Config::SimConfig& simConfig);
|
||||
void loadMemSpec(const DRAMSys::Config::MemSpec& memSpec);
|
||||
};
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
#endif // CONFIGURATION_H
|
||||
@@ -42,8 +42,7 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
MemSpec::MemSpec(const DRAMSys::Config::MemSpec& memSpec,
|
||||
MemoryType memoryType,
|
||||
MemSpec::MemSpec(const Config::MemSpec& memSpec,
|
||||
unsigned numberOfChannels,
|
||||
unsigned pseudoChannelsPerChannel,
|
||||
unsigned ranksPerChannel,
|
||||
@@ -78,7 +77,7 @@ MemSpec::MemSpec(const DRAMSys::Config::MemSpec& memSpec,
|
||||
fCKMHz(memSpec.memtimingspec.entries.at("clkMhz")),
|
||||
tCK(sc_time(1.0 / fCKMHz, SC_US)),
|
||||
memoryId(memSpec.memoryId),
|
||||
memoryType(memoryType),
|
||||
memoryType(memSpec.memoryType),
|
||||
burstDuration(tCK * (static_cast<double>(defaultBurstLength) / dataRate))
|
||||
|
||||
{
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
#include "DRAMSys/common/utils.h"
|
||||
#include "DRAMSys/config/DRAMSysConfiguration.h"
|
||||
#include "DRAMSys/config/memspec/MemSpec.h"
|
||||
#include "DRAMSys/controller/Command.h"
|
||||
|
||||
#include <string>
|
||||
@@ -87,21 +88,7 @@ public:
|
||||
const sc_core::sc_time tCK;
|
||||
|
||||
const std::string memoryId;
|
||||
const enum class MemoryType {
|
||||
DDR3,
|
||||
DDR4,
|
||||
DDR5,
|
||||
LPDDR4,
|
||||
LPDDR5,
|
||||
WideIO,
|
||||
WideIO2,
|
||||
GDDR5,
|
||||
GDDR5X,
|
||||
GDDR6,
|
||||
HBM2,
|
||||
HBM3,
|
||||
STTMRAM
|
||||
} memoryType;
|
||||
const Config::MemoryType memoryType;
|
||||
|
||||
[[nodiscard]] virtual sc_core::sc_time getRefreshIntervalAB() const;
|
||||
[[nodiscard]] virtual sc_core::sc_time getRefreshIntervalPB() const;
|
||||
@@ -131,8 +118,7 @@ public:
|
||||
#endif
|
||||
|
||||
protected:
|
||||
MemSpec(const DRAMSys::Config::MemSpec& memSpec,
|
||||
MemoryType memoryType,
|
||||
MemSpec(const Config::MemSpec& memSpec,
|
||||
unsigned numberOfChannels,
|
||||
unsigned pseudoChannelsPerChannel,
|
||||
unsigned ranksPerChannel,
|
||||
|
||||
@@ -46,9 +46,8 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
MemSpecDDR3::MemSpecDDR3(const DRAMSys::Config::MemSpec& memSpec) :
|
||||
MemSpecDDR3::MemSpecDDR3(const Config::MemSpec& memSpec) :
|
||||
MemSpec(memSpec,
|
||||
MemoryType::DDR3,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
|
||||
1,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace DRAMSys
|
||||
class MemSpecDDR3 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
explicit MemSpecDDR3(const DRAMSys::Config::MemSpec& memSpec);
|
||||
explicit MemSpecDDR3(const Config::MemSpec& memSpec);
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_core::sc_time tCKE;
|
||||
|
||||
@@ -46,9 +46,8 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
MemSpecDDR4::MemSpecDDR4(const DRAMSys::Config::MemSpec& memSpec) :
|
||||
MemSpecDDR4::MemSpecDDR4(const Config::MemSpec& memSpec) :
|
||||
MemSpec(memSpec,
|
||||
MemoryType::DDR4,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
|
||||
1,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace DRAMSys
|
||||
class MemSpecDDR4 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
explicit MemSpecDDR4(const DRAMSys::Config::MemSpec& memSpec);
|
||||
explicit MemSpecDDR4(const Config::MemSpec& memSpec);
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_core::sc_time tCKE;
|
||||
|
||||
@@ -46,9 +46,8 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
MemSpecGDDR5::MemSpecGDDR5(const DRAMSys::Config::MemSpec& memSpec) :
|
||||
MemSpecGDDR5::MemSpecGDDR5(const Config::MemSpec& memSpec) :
|
||||
MemSpec(memSpec,
|
||||
MemoryType::GDDR5,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
|
||||
1,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace DRAMSys
|
||||
class MemSpecGDDR5 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
explicit MemSpecGDDR5(const DRAMSys::Config::MemSpec& memSpec);
|
||||
explicit MemSpecGDDR5(const Config::MemSpec& memSpec);
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_core::sc_time tRP;
|
||||
|
||||
@@ -46,9 +46,8 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
MemSpecGDDR5X::MemSpecGDDR5X(const DRAMSys::Config::MemSpec& memSpec) :
|
||||
MemSpecGDDR5X::MemSpecGDDR5X(const Config::MemSpec& memSpec) :
|
||||
MemSpec(memSpec,
|
||||
MemoryType::GDDR5X,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
|
||||
1,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace DRAMSys
|
||||
class MemSpecGDDR5X final : public MemSpec
|
||||
{
|
||||
public:
|
||||
explicit MemSpecGDDR5X(const DRAMSys::Config::MemSpec& memSpec);
|
||||
explicit MemSpecGDDR5X(const Config::MemSpec& memSpec);
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_core::sc_time tRP;
|
||||
|
||||
@@ -46,9 +46,8 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
MemSpecGDDR6::MemSpecGDDR6(const DRAMSys::Config::MemSpec& memSpec) :
|
||||
MemSpecGDDR6::MemSpecGDDR6(const Config::MemSpec& memSpec) :
|
||||
MemSpec(memSpec,
|
||||
MemoryType::GDDR6,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
|
||||
1,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace DRAMSys
|
||||
struct MemSpecGDDR6 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
explicit MemSpecGDDR6(const DRAMSys::Config::MemSpec& memSpec);
|
||||
explicit MemSpecGDDR6(const Config::MemSpec& memSpec);
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_core::sc_time tRP;
|
||||
|
||||
@@ -46,9 +46,8 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
MemSpecHBM2::MemSpecHBM2(const DRAMSys::Config::MemSpec& memSpec) :
|
||||
MemSpecHBM2::MemSpecHBM2(const Config::MemSpec& memSpec) :
|
||||
MemSpec(memSpec,
|
||||
MemoryType::HBM2,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace DRAMSys
|
||||
class MemSpecHBM2 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
explicit MemSpecHBM2(const DRAMSys::Config::MemSpec& memSpec);
|
||||
explicit MemSpecHBM2(const Config::MemSpec& memSpec);
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_core::sc_time tDQSCK;
|
||||
|
||||
@@ -46,9 +46,8 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
MemSpecLPDDR4::MemSpecLPDDR4(const DRAMSys::Config::MemSpec& memSpec) :
|
||||
MemSpecLPDDR4::MemSpecLPDDR4(const Config::MemSpec& memSpec) :
|
||||
MemSpec(memSpec,
|
||||
MemoryType::LPDDR4,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
|
||||
1,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace DRAMSys
|
||||
class MemSpecLPDDR4 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
explicit MemSpecLPDDR4(const DRAMSys::Config::MemSpec& memSpec);
|
||||
explicit MemSpecLPDDR4(const Config::MemSpec& memSpec);
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_core::sc_time tREFI;
|
||||
|
||||
@@ -46,9 +46,8 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
MemSpecSTTMRAM::MemSpecSTTMRAM(const DRAMSys::Config::MemSpec& memSpec) :
|
||||
MemSpecSTTMRAM::MemSpecSTTMRAM(const Config::MemSpec& memSpec) :
|
||||
MemSpec(memSpec,
|
||||
MemoryType::STTMRAM,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
|
||||
1,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace DRAMSys
|
||||
class MemSpecSTTMRAM final : public MemSpec
|
||||
{
|
||||
public:
|
||||
explicit MemSpecSTTMRAM(const DRAMSys::Config::MemSpec& memSpec);
|
||||
explicit MemSpecSTTMRAM(const Config::MemSpec& memSpec);
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_core::sc_time tCKE;
|
||||
|
||||
@@ -46,9 +46,8 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
MemSpecWideIO::MemSpecWideIO(const DRAMSys::Config::MemSpec& memSpec) :
|
||||
MemSpecWideIO::MemSpecWideIO(const Config::MemSpec& memSpec) :
|
||||
MemSpec(memSpec,
|
||||
MemoryType::WideIO,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
|
||||
1,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace DRAMSys
|
||||
class MemSpecWideIO final : public MemSpec
|
||||
{
|
||||
public:
|
||||
explicit MemSpecWideIO(const DRAMSys::Config::MemSpec& memSpec);
|
||||
explicit MemSpecWideIO(const Config::MemSpec& memSpec);
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_core::sc_time tCKE;
|
||||
|
||||
@@ -46,9 +46,8 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
MemSpecWideIO2::MemSpecWideIO2(const DRAMSys::Config::MemSpec& memSpec) :
|
||||
MemSpecWideIO2::MemSpecWideIO2(const Config::MemSpec& memSpec) :
|
||||
MemSpec(memSpec,
|
||||
MemoryType::WideIO2,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
|
||||
1,
|
||||
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace DRAMSys
|
||||
class MemSpecWideIO2 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
explicit MemSpecWideIO2(const DRAMSys::Config::MemSpec& memSpec);
|
||||
explicit MemSpecWideIO2(const Config::MemSpec& memSpec);
|
||||
|
||||
// Memspec Variables:
|
||||
const sc_core::sc_time tDQSCK;
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
|
||||
#include "BankMachine.h"
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace sc_core;
|
||||
@@ -44,8 +42,11 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
BankMachine::BankMachine(const Configuration& config, const SchedulerIF& scheduler, Bank bank) :
|
||||
memSpec(*config.memSpec),
|
||||
BankMachine::BankMachine(const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
const SchedulerIF& scheduler,
|
||||
Bank bank) :
|
||||
memSpec(memSpec),
|
||||
scheduler(scheduler),
|
||||
bank(bank),
|
||||
bankgroup(BankGroup(static_cast<std::size_t>(bank) / memSpec.banksPerGroup)),
|
||||
@@ -181,10 +182,11 @@ bool BankMachine::isPrecharged() const
|
||||
return state == State::Precharged;
|
||||
}
|
||||
|
||||
BankMachineOpen::BankMachineOpen(const Configuration& config,
|
||||
BankMachineOpen::BankMachineOpen(const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
const SchedulerIF& scheduler,
|
||||
Bank bank) :
|
||||
BankMachine(config, scheduler, bank)
|
||||
BankMachine(config, memSpec, scheduler, bank)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -230,10 +232,11 @@ void BankMachineOpen::evaluate()
|
||||
}
|
||||
}
|
||||
|
||||
BankMachineClosed::BankMachineClosed(const Configuration& config,
|
||||
BankMachineClosed::BankMachineClosed(const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
const SchedulerIF& scheduler,
|
||||
Bank bank) :
|
||||
BankMachine(config, scheduler, bank)
|
||||
BankMachine(config, memSpec, scheduler, bank)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -274,10 +277,11 @@ void BankMachineClosed::evaluate()
|
||||
}
|
||||
}
|
||||
|
||||
BankMachineOpenAdaptive::BankMachineOpenAdaptive(const Configuration& config,
|
||||
BankMachineOpenAdaptive::BankMachineOpenAdaptive(const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
const SchedulerIF& scheduler,
|
||||
Bank bank) :
|
||||
BankMachine(config, scheduler, bank)
|
||||
BankMachine(config, memSpec, scheduler, bank)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -338,10 +342,11 @@ void BankMachineOpenAdaptive::evaluate()
|
||||
}
|
||||
}
|
||||
|
||||
BankMachineClosedAdaptive::BankMachineClosedAdaptive(const Configuration& config,
|
||||
BankMachineClosedAdaptive::BankMachineClosedAdaptive(const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
const SchedulerIF& scheduler,
|
||||
Bank bank) :
|
||||
BankMachine(config, scheduler, bank)
|
||||
BankMachine(config, memSpec, scheduler, bank)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
#define BANKMACHINE_H
|
||||
|
||||
#include "DRAMSys/common/dramExtensions.h"
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpec.h"
|
||||
#include "DRAMSys/controller/Command.h"
|
||||
#include "DRAMSys/controller/ManagerIF.h"
|
||||
#include "DRAMSys/controller/McConfig.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
|
||||
|
||||
@@ -71,7 +71,7 @@ protected:
|
||||
Precharged,
|
||||
Activated
|
||||
} state = State::Precharged;
|
||||
BankMachine(const Configuration& config, const SchedulerIF& scheduler, Bank bank);
|
||||
BankMachine(const McConfig& config, const MemSpec& memSpec, const SchedulerIF& scheduler, Bank bank);
|
||||
const MemSpec& memSpec;
|
||||
tlm::tlm_generic_payload* currentPayload = nullptr;
|
||||
const SchedulerIF& scheduler;
|
||||
@@ -90,28 +90,28 @@ protected:
|
||||
class BankMachineOpen final : public BankMachine
|
||||
{
|
||||
public:
|
||||
BankMachineOpen(const Configuration& config, const SchedulerIF& scheduler, Bank bank);
|
||||
BankMachineOpen(const McConfig& config, const MemSpec& memSpec, const SchedulerIF& scheduler, Bank bank);
|
||||
void evaluate() override;
|
||||
};
|
||||
|
||||
class BankMachineClosed final : public BankMachine
|
||||
{
|
||||
public:
|
||||
BankMachineClosed(const Configuration& config, const SchedulerIF& scheduler, Bank bank);
|
||||
BankMachineClosed(const McConfig& config, const MemSpec& memSpec, const SchedulerIF& scheduler, Bank bank);
|
||||
void evaluate() override;
|
||||
};
|
||||
|
||||
class BankMachineOpenAdaptive final : public BankMachine
|
||||
{
|
||||
public:
|
||||
BankMachineOpenAdaptive(const Configuration& config, const SchedulerIF& scheduler, Bank bank);
|
||||
BankMachineOpenAdaptive(const McConfig& config, const MemSpec& memSpec, const SchedulerIF& scheduler, Bank bank);
|
||||
void evaluate() override;
|
||||
};
|
||||
|
||||
class BankMachineClosedAdaptive final : public BankMachine
|
||||
{
|
||||
public:
|
||||
BankMachineClosedAdaptive(const Configuration& config, const SchedulerIF& scheduler, Bank bank);
|
||||
BankMachineClosedAdaptive(const McConfig& config, const MemSpec& memSpec, const SchedulerIF& scheduler, Bank bank);
|
||||
void evaluate() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -29,13 +29,15 @@
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
* Authors:
|
||||
* Lukas Steiner
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include "Controller.h"
|
||||
|
||||
#include "DRAMSys/common/dramExtensions.h"
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/config/McConfig.h"
|
||||
#include "DRAMSys/controller/checker/CheckerDDR3.h"
|
||||
#include "DRAMSys/controller/checker/CheckerDDR4.h"
|
||||
#include "DRAMSys/controller/checker/CheckerGDDR5.h"
|
||||
@@ -80,19 +82,15 @@ namespace DRAMSys
|
||||
{
|
||||
|
||||
Controller::Controller(const sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder) :
|
||||
sc_module(name),
|
||||
config(config),
|
||||
memSpec(memSpec),
|
||||
thinkDelayFw(config.thinkDelayFw),
|
||||
thinkDelayBw(config.thinkDelayBw),
|
||||
phyDelayFw(config.phyDelayFw),
|
||||
phyDelayBw(config.phyDelayBw),
|
||||
blockingReadDelay(config.blockingReadDelay),
|
||||
blockingWriteDelay(config.blockingWriteDelay),
|
||||
addressDecoder(addressDecoder),
|
||||
minBytesPerBurst(config.memSpec->defaultBytesPerBurst),
|
||||
maxBytesPerBurst(config.memSpec->maxBytesPerBurst)
|
||||
minBytesPerBurst(memSpec.defaultBytesPerBurst),
|
||||
maxBytesPerBurst(memSpec.maxBytesPerBurst)
|
||||
{
|
||||
SC_METHOD(controllerMethod);
|
||||
sensitive << beginReqEvent << endRespEvent << controllerEvent << dataResponseEvent;
|
||||
@@ -110,95 +108,130 @@ Controller::Controller(const sc_module_name& name,
|
||||
readyCommands.reserve(memSpec.banksPerChannel);
|
||||
|
||||
// instantiate timing checker
|
||||
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::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::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);
|
||||
try
|
||||
{
|
||||
if (memSpec.memoryType == Config::MemoryType::DDR3)
|
||||
{
|
||||
checker = std::make_unique<CheckerDDR3>(dynamic_cast<const MemSpecDDR3&>(memSpec));
|
||||
}
|
||||
else if (memSpec.memoryType == Config::MemoryType::DDR4)
|
||||
{
|
||||
checker = std::make_unique<CheckerDDR4>(dynamic_cast<const MemSpecDDR4&>(memSpec));
|
||||
}
|
||||
else if (memSpec.memoryType == Config::MemoryType::WideIO)
|
||||
{
|
||||
checker = std::make_unique<CheckerWideIO>(dynamic_cast<const MemSpecWideIO&>(memSpec));
|
||||
}
|
||||
else if (memSpec.memoryType == Config::MemoryType::LPDDR4)
|
||||
{
|
||||
checker = std::make_unique<CheckerLPDDR4>(dynamic_cast<const MemSpecLPDDR4&>(memSpec));
|
||||
}
|
||||
else if (memSpec.memoryType == Config::MemoryType::WideIO2)
|
||||
{
|
||||
checker =
|
||||
std::make_unique<CheckerWideIO2>(dynamic_cast<const MemSpecWideIO2&>(memSpec));
|
||||
}
|
||||
else if (memSpec.memoryType == Config::MemoryType::HBM2)
|
||||
{
|
||||
checker = std::make_unique<CheckerHBM2>(dynamic_cast<const MemSpecHBM2&>(memSpec));
|
||||
}
|
||||
else if (memSpec.memoryType == Config::MemoryType::GDDR5)
|
||||
{
|
||||
checker = std::make_unique<CheckerGDDR5>(dynamic_cast<const MemSpecGDDR5&>(memSpec));
|
||||
}
|
||||
else if (memSpec.memoryType == Config::MemoryType::GDDR5X)
|
||||
{
|
||||
checker = std::make_unique<CheckerGDDR5X>(dynamic_cast<const MemSpecGDDR5X&>(memSpec));
|
||||
}
|
||||
else if (memSpec.memoryType == Config::MemoryType::GDDR6)
|
||||
{
|
||||
checker = std::make_unique<CheckerGDDR6>(dynamic_cast<const MemSpecGDDR6&>(memSpec));
|
||||
}
|
||||
else if (memSpec.memoryType == Config::MemoryType::STTMRAM)
|
||||
{
|
||||
checker =
|
||||
std::make_unique<CheckerSTTMRAM>(dynamic_cast<const MemSpecSTTMRAM&>(memSpec));
|
||||
}
|
||||
#ifdef DDR5_SIM
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::DDR5)
|
||||
checker = std::make_unique<CheckerDDR5>(config);
|
||||
else if (memSpec.memoryType == Config::MemoryType::DDR5)
|
||||
{
|
||||
checker = std::make_unique<CheckerDDR5>(dynamic_cast<const MemSpecDDR5&>(memSpec));
|
||||
}
|
||||
#endif
|
||||
#ifdef LPDDR5_SIM
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::LPDDR5)
|
||||
checker = std::make_unique<CheckerLPDDR5>(config);
|
||||
else if (memSpec.memoryType == Config::MemoryType::LPDDR5)
|
||||
{
|
||||
checker = std::make_unique<CheckerLPDDR5>(dynamic_cast<const MemSpecLPDDR5&>(memSpec));
|
||||
}
|
||||
#endif
|
||||
#ifdef HBM3_SIM
|
||||
else if (memSpec.memoryType == MemSpec::MemoryType::HBM3)
|
||||
checker = std::make_unique<CheckerHBM3>(config);
|
||||
else if (memSpec.memoryType == Config::MemoryType::HBM3)
|
||||
{
|
||||
checker = std::make_unique<CheckerHBM3>(dynamic_cast<const MemSpecHBM3&>(memSpec));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (const std::bad_cast& e)
|
||||
{
|
||||
SC_REPORT_FATAL(sc_module::name(), "Wrong MemSpec chosen");
|
||||
}
|
||||
|
||||
// instantiate scheduler and command mux
|
||||
if (config.scheduler == Configuration::Scheduler::Fifo)
|
||||
scheduler = std::make_unique<SchedulerFifo>(config);
|
||||
else if (config.scheduler == Configuration::Scheduler::FrFcfs)
|
||||
scheduler = std::make_unique<SchedulerFrFcfs>(config);
|
||||
else if (config.scheduler == Configuration::Scheduler::FrFcfsGrp)
|
||||
scheduler = std::make_unique<SchedulerFrFcfsGrp>(config);
|
||||
else if (config.scheduler == Configuration::Scheduler::GrpFrFcfs)
|
||||
scheduler = std::make_unique<SchedulerGrpFrFcfs>(config);
|
||||
else if (config.scheduler == Configuration::Scheduler::GrpFrFcfsWm)
|
||||
scheduler = std::make_unique<SchedulerGrpFrFcfsWm>(config);
|
||||
if (config.scheduler == Config::SchedulerType::Fifo)
|
||||
scheduler = std::make_unique<SchedulerFifo>(config, memSpec);
|
||||
else if (config.scheduler == Config::SchedulerType::FrFcfs)
|
||||
scheduler = std::make_unique<SchedulerFrFcfs>(config, memSpec);
|
||||
else if (config.scheduler == Config::SchedulerType::FrFcfsGrp)
|
||||
scheduler = std::make_unique<SchedulerFrFcfsGrp>(config, memSpec);
|
||||
else if (config.scheduler == Config::SchedulerType::GrpFrFcfs)
|
||||
scheduler = std::make_unique<SchedulerGrpFrFcfs>(config, memSpec);
|
||||
else if (config.scheduler == Config::SchedulerType::GrpFrFcfsWm)
|
||||
scheduler = std::make_unique<SchedulerGrpFrFcfsWm>(config, memSpec);
|
||||
|
||||
if (config.cmdMux == Configuration::CmdMux::Oldest)
|
||||
if (config.cmdMux == Config::CmdMuxType::Oldest)
|
||||
{
|
||||
if (memSpec.hasRasAndCasBus())
|
||||
cmdMux = std::make_unique<CmdMuxOldestRasCas>(config);
|
||||
cmdMux = std::make_unique<CmdMuxOldestRasCas>(memSpec);
|
||||
else
|
||||
cmdMux = std::make_unique<CmdMuxOldest>(config);
|
||||
cmdMux = std::make_unique<CmdMuxOldest>(memSpec);
|
||||
}
|
||||
else if (config.cmdMux == Configuration::CmdMux::Strict)
|
||||
else if (config.cmdMux == Config::CmdMuxType::Strict)
|
||||
{
|
||||
if (memSpec.hasRasAndCasBus())
|
||||
cmdMux = std::make_unique<CmdMuxStrictRasCas>(config);
|
||||
cmdMux = std::make_unique<CmdMuxStrictRasCas>(memSpec);
|
||||
else
|
||||
cmdMux = std::make_unique<CmdMuxStrict>(config);
|
||||
cmdMux = std::make_unique<CmdMuxStrict>(memSpec);
|
||||
}
|
||||
|
||||
if (config.respQueue == Configuration::RespQueue::Fifo)
|
||||
if (config.respQueue == Config::RespQueueType::Fifo)
|
||||
respQueue = std::make_unique<RespQueueFifo>();
|
||||
else if (config.respQueue == Configuration::RespQueue::Reorder)
|
||||
else if (config.respQueue == Config::RespQueueType::Reorder)
|
||||
respQueue = std::make_unique<RespQueueReorder>();
|
||||
|
||||
// instantiate bank machines (one per bank)
|
||||
if (config.pagePolicy == Configuration::PagePolicy::Open)
|
||||
if (config.pagePolicy == Config::PagePolicyType::Open)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||
bankMachines.push_back(
|
||||
std::make_unique<BankMachineOpen>(config, *scheduler, Bank(bankID)));
|
||||
std::make_unique<BankMachineOpen>(config, memSpec, *scheduler, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == Configuration::PagePolicy::OpenAdaptive)
|
||||
else if (config.pagePolicy == Config::PagePolicyType::OpenAdaptive)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||
bankMachines.push_back(
|
||||
std::make_unique<BankMachineOpenAdaptive>(config, *scheduler, Bank(bankID)));
|
||||
bankMachines.push_back(std::make_unique<BankMachineOpenAdaptive>(
|
||||
config, memSpec, *scheduler, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == Configuration::PagePolicy::Closed)
|
||||
else if (config.pagePolicy == Config::PagePolicyType::Closed)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||
bankMachines.push_back(
|
||||
std::make_unique<BankMachineClosed>(config, *scheduler, Bank(bankID)));
|
||||
std::make_unique<BankMachineClosed>(config, memSpec, *scheduler, Bank(bankID)));
|
||||
}
|
||||
else if (config.pagePolicy == Configuration::PagePolicy::ClosedAdaptive)
|
||||
else if (config.pagePolicy == Config::PagePolicyType::ClosedAdaptive)
|
||||
{
|
||||
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
|
||||
bankMachines.push_back(
|
||||
std::make_unique<BankMachineClosedAdaptive>(config, *scheduler, Bank(bankID)));
|
||||
bankMachines.push_back(std::make_unique<BankMachineClosedAdaptive>(
|
||||
config, memSpec, *scheduler, Bank(bankID)));
|
||||
}
|
||||
|
||||
bankMachinesOnRank = ControllerVector<Rank, ControllerVector<Bank, BankMachine*>>(
|
||||
@@ -211,12 +244,12 @@ Controller::Controller(const sc_module_name& name,
|
||||
}
|
||||
|
||||
// instantiate power-down managers (one per rank)
|
||||
if (config.powerDownPolicy == Configuration::PowerDownPolicy::NoPowerDown)
|
||||
if (config.powerDownPolicy == Config::PowerDownPolicyType::NoPowerDown)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
powerDownManagers.push_back(std::make_unique<PowerDownManagerDummy>());
|
||||
}
|
||||
else if (config.powerDownPolicy == Configuration::PowerDownPolicy::Staggered)
|
||||
else if (config.powerDownPolicy == Config::PowerDownPolicyType::Staggered)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
@@ -226,52 +259,56 @@ Controller::Controller(const sc_module_name& name,
|
||||
}
|
||||
|
||||
// instantiate refresh managers (one per rank)
|
||||
if (config.refreshPolicy == Configuration::RefreshPolicy::NoRefresh)
|
||||
if (config.refreshPolicy == Config::RefreshPolicyType::NoRefresh)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
refreshManagers.push_back(std::make_unique<RefreshManagerDummy>());
|
||||
}
|
||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::AllBank)
|
||||
else if (config.refreshPolicy == Config::RefreshPolicyType::AllBank)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
refreshManagers.push_back(
|
||||
std::make_unique<RefreshManagerAllBank>(config,
|
||||
memSpec,
|
||||
bankMachinesOnRank[Rank(rankID)],
|
||||
*powerDownManagers[Rank(rankID)],
|
||||
Rank(rankID)));
|
||||
}
|
||||
}
|
||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::SameBank)
|
||||
else if (config.refreshPolicy == Config::RefreshPolicyType::SameBank)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
refreshManagers.push_back(
|
||||
std::make_unique<RefreshManagerSameBank>(config,
|
||||
memSpec,
|
||||
bankMachinesOnRank[Rank(rankID)],
|
||||
*powerDownManagers[Rank(rankID)],
|
||||
Rank(rankID)));
|
||||
}
|
||||
}
|
||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::PerBank)
|
||||
else if (config.refreshPolicy == Config::RefreshPolicyType::PerBank)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
// TODO: remove bankMachines in constructor
|
||||
refreshManagers.push_back(
|
||||
std::make_unique<RefreshManagerPerBank>(config,
|
||||
memSpec,
|
||||
bankMachinesOnRank[Rank(rankID)],
|
||||
*powerDownManagers[Rank(rankID)],
|
||||
Rank(rankID)));
|
||||
}
|
||||
}
|
||||
else if (config.refreshPolicy == Configuration::RefreshPolicy::Per2Bank)
|
||||
else if (config.refreshPolicy == Config::RefreshPolicyType::Per2Bank)
|
||||
{
|
||||
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
|
||||
{
|
||||
// TODO: remove bankMachines in constructor
|
||||
refreshManagers.push_back(
|
||||
std::make_unique<RefreshManagerPer2Bank>(config,
|
||||
memSpec,
|
||||
bankMachinesOnRank[Rank(rankID)],
|
||||
*powerDownManagers[Rank(rankID)],
|
||||
Rank(rankID)));
|
||||
@@ -379,11 +416,11 @@ void Controller::controllerMethod()
|
||||
if (command.isCasCommand())
|
||||
{
|
||||
scheduler->removeRequest(*trans);
|
||||
manageRequests(thinkDelayFw);
|
||||
manageRequests(config.thinkDelayFw);
|
||||
respQueue->insertPayload(trans,
|
||||
sc_time_stamp() + thinkDelayFw + phyDelayFw +
|
||||
sc_time_stamp() + config.thinkDelayFw + config.phyDelayFw +
|
||||
memSpec.getIntervalOnDataStrobe(command, *trans).end +
|
||||
phyDelayBw + thinkDelayBw);
|
||||
config.phyDelayBw + config.thinkDelayBw);
|
||||
|
||||
sc_time triggerTime = respQueue->getTriggerTime();
|
||||
if (triggerTime != scMaxTime)
|
||||
@@ -394,7 +431,7 @@ void Controller::controllerMethod()
|
||||
if (ranksNumberOfPayloads[rank] == 0)
|
||||
powerDownManagers[rank]->triggerEntry();
|
||||
|
||||
sc_time fwDelay = thinkDelayFw + phyDelayFw;
|
||||
sc_time fwDelay = config.thinkDelayFw + config.phyDelayFw;
|
||||
tlm_phase phase = command.toPhase();
|
||||
iSocket->nb_transport_fw(*trans, phase, fwDelay);
|
||||
}
|
||||
@@ -489,7 +526,7 @@ tlm_sync_enum Controller::nb_transport_bw([[maybe_unused]] tlm_generic_payload&
|
||||
void Controller::b_transport(tlm_generic_payload& trans, sc_time& delay)
|
||||
{
|
||||
iSocket->b_transport(trans, delay);
|
||||
delay += trans.is_write() ? blockingWriteDelay : blockingReadDelay;
|
||||
delay += trans.is_write() ? config.blockingWriteDelay : config.blockingReadDelay;
|
||||
}
|
||||
|
||||
unsigned int Controller::transport_dbg(tlm_generic_payload& trans)
|
||||
|
||||
@@ -29,21 +29,25 @@
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Author: Lukas Steiner
|
||||
* Authors:
|
||||
* Lukas Steiner
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#ifndef CONTROLLER_H
|
||||
#define CONTROLLER_H
|
||||
|
||||
#include "DRAMSys/common/DebugManager.h"
|
||||
#include "DRAMSys/controller/BankMachine.h"
|
||||
#include "DRAMSys/controller/Command.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
#include "DRAMSys/controller/cmdmux/CmdMuxIF.h"
|
||||
#include "DRAMSys/controller/powerdown/PowerDownManagerIF.h"
|
||||
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
|
||||
#include "DRAMSys/controller/respqueue/RespQueueIF.h"
|
||||
#include "DRAMSys/simulation/AddressDecoder.h"
|
||||
#include "BankMachine.h"
|
||||
#include "Command.h"
|
||||
#include "McConfig.h"
|
||||
#include "checker/CheckerIF.h"
|
||||
#include "cmdmux/CmdMuxIF.h"
|
||||
#include "powerdown/PowerDownManagerIF.h"
|
||||
#include "refresh/RefreshManagerIF.h"
|
||||
#include "respqueue/RespQueueIF.h"
|
||||
|
||||
#include <DRAMSys/common/DebugManager.h>
|
||||
#include <DRAMSys/simulation/AddressDecoder.h>
|
||||
|
||||
#include <functional>
|
||||
#include <stack>
|
||||
@@ -64,7 +68,7 @@ public:
|
||||
tlm_utils::simple_initiator_socket<Controller> iSocket{"iSocket"}; // DRAM side
|
||||
|
||||
Controller(const sc_core::sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder);
|
||||
SC_HAS_PROCESS(Controller);
|
||||
@@ -76,11 +80,11 @@ protected:
|
||||
void end_of_simulation() override;
|
||||
|
||||
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans,
|
||||
tlm::tlm_phase& phase,
|
||||
sc_core::sc_time& delay);
|
||||
tlm::tlm_phase& phase,
|
||||
sc_core::sc_time& delay);
|
||||
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans,
|
||||
tlm::tlm_phase& phase,
|
||||
sc_core::sc_time& delay);
|
||||
tlm::tlm_phase& phase,
|
||||
sc_core::sc_time& delay);
|
||||
void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay);
|
||||
unsigned int transport_dbg(tlm::tlm_generic_payload& trans);
|
||||
|
||||
@@ -89,16 +93,13 @@ protected:
|
||||
|
||||
virtual void controllerMethod();
|
||||
|
||||
const McConfig& config;
|
||||
const MemSpec& memSpec;
|
||||
const AddressDecoder& addressDecoder;
|
||||
|
||||
std::unique_ptr<SchedulerIF> scheduler;
|
||||
|
||||
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
const sc_core::sc_time thinkDelayFw;
|
||||
const sc_core::sc_time thinkDelayBw;
|
||||
const sc_core::sc_time phyDelayFw;
|
||||
const sc_core::sc_time phyDelayBw;
|
||||
const sc_core::sc_time blockingReadDelay;
|
||||
const sc_core::sc_time blockingWriteDelay;
|
||||
sc_core::sc_time scMaxTime = sc_core::sc_max_time();
|
||||
|
||||
uint64_t numberOfBeatsServed = 0;
|
||||
unsigned totalNumberOfPayloads = 0;
|
||||
@@ -114,7 +115,6 @@ protected:
|
||||
ControllerVector<Rank, std::unique_ptr<RefreshManagerIF>> refreshManagers;
|
||||
ControllerVector<Rank, std::unique_ptr<PowerDownManagerIF>> powerDownManagers;
|
||||
|
||||
const AddressDecoder& addressDecoder;
|
||||
uint64_t nextChannelPayloadIDToAppend = 1;
|
||||
|
||||
struct PayloadAndArrival
|
||||
|
||||
@@ -43,15 +43,16 @@ namespace DRAMSys
|
||||
{
|
||||
|
||||
ControllerRecordable::ControllerRecordable(const sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const McConfig& config,
|
||||
const SimConfig& simConfig,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder,
|
||||
TlmRecorder& tlmRecorder) :
|
||||
Controller(name, config, memSpec, addressDecoder),
|
||||
tlmRecorder(tlmRecorder),
|
||||
windowSizeTime(config.windowSize * memSpec.tCK),
|
||||
activeTimeMultiplier(config.memSpec->tCK / config.memSpec->dataRate),
|
||||
enableWindowing(config.enableWindowing)
|
||||
windowSizeTime(simConfig.windowSize * memSpec.tCK),
|
||||
activeTimeMultiplier(memSpec.tCK / memSpec.dataRate),
|
||||
enableWindowing(simConfig.enableWindowing)
|
||||
{
|
||||
if (enableWindowing)
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "DRAMSys/common/TlmRecorder.h"
|
||||
#include "DRAMSys/controller/Controller.h"
|
||||
#include "DRAMSys/simulation/SimConfig.h"
|
||||
|
||||
#include <systemc>
|
||||
#include <tlm>
|
||||
@@ -48,7 +49,8 @@ class ControllerRecordable final : public Controller
|
||||
{
|
||||
public:
|
||||
ControllerRecordable(const sc_core::sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const McConfig& config,
|
||||
const SimConfig& simConfig,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder,
|
||||
TlmRecorder& tlmRecorder);
|
||||
|
||||
124
src/libdramsys/DRAMSys/controller/McConfig.cpp
Normal file
124
src/libdramsys/DRAMSys/controller/McConfig.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2024, RPTU Kaiserslautern-Landau
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include "McConfig.h"
|
||||
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
McConfig::McConfig(const Config::McConfig& config, const MemSpec& memSpec) :
|
||||
pagePolicy(config.PagePolicy.value_or(DEFAULT_PAGE_POLICY)),
|
||||
scheduler(config.Scheduler.value_or(DEFAULT_SCHEDULER)),
|
||||
schedulerBuffer(config.SchedulerBuffer.value_or(DEFAULT_SCHEDULER_BUFFER)),
|
||||
lowWatermark(config.LowWatermark.value_or(DEFAULT_LOW_WATERMARK)),
|
||||
highWatermark(config.HighWatermark.value_or(DEFAULT_HIGH_WATERMARK)),
|
||||
cmdMux(config.CmdMux.value_or(DEFAULT_CMD_MUX)),
|
||||
respQueue(config.RespQueue.value_or(DEFAULT_RESP_QUEUE)),
|
||||
arbiter(config.Arbiter.value_or(DEFAULT_ARBITER)),
|
||||
requestBufferSize(config.RequestBufferSize.value_or(DEFAULT_REQUEST_BUFFER_SIZE)),
|
||||
requestBufferSizeRead(config.RequestBufferSizeRead.value_or(DEFAULT_REQUEST_BUFFER_SIZE_READ)),
|
||||
requestBufferSizeWrite(
|
||||
config.RequestBufferSizeWrite.value_or(DEFAULT_REQUEST_BUFFER_SIZE_WRITE)),
|
||||
refreshPolicy(config.RefreshPolicy.value_or(DEFAULT_REFRESH_POLICY)),
|
||||
refreshMaxPostponed(config.RefreshMaxPostponed.value_or(DEFAULT_REFRESH_MAX_POSTPONED)),
|
||||
refreshMaxPulledin(config.RefreshMaxPulledin.value_or(DEFAULT_REFRESH_MAX_PULLEDIN)),
|
||||
powerDownPolicy(config.PowerDownPolicy.value_or(DEFAULT_POWER_DOWN_POLICY)),
|
||||
maxActiveTransactions(config.MaxActiveTransactions.value_or(DEFAULT_MAX_ACTIVE_TRANSACTIONS)),
|
||||
refreshManagement(config.RefreshManagement.value_or(DEFAULT_REFRESH_MANAGEMENT)),
|
||||
arbitrationDelayFw(sc_core::sc_time(
|
||||
config.ArbitrationDelayFw.value_or(DEFAULT_ARBITRATION_DELAY_FW_NS), sc_core::SC_NS)),
|
||||
arbitrationDelayBw(sc_core::sc_time(
|
||||
config.ArbitrationDelayBw.value_or(DEFAULT_ARBITRATION_DELAY_BW_NS), sc_core::SC_NS)),
|
||||
thinkDelayFw(
|
||||
sc_core::sc_time(config.ThinkDelayFw.value_or(DEFAULT_THINK_DELAY_FW_NS), sc_core::SC_NS)),
|
||||
thinkDelayBw(
|
||||
sc_core::sc_time(config.ThinkDelayBw.value_or(DEFAULT_THINK_DELAY_BW_NS), sc_core::SC_NS)),
|
||||
phyDelayFw(
|
||||
sc_core::sc_time(config.PhyDelayFw.value_or(DEFAULT_PHY_DELAY_FW_NS), sc_core::SC_NS)),
|
||||
phyDelayBw(
|
||||
sc_core::sc_time(config.PhyDelayBw.value_or(DEFAULT_PHY_DELAY_BW_NS), sc_core::SC_NS)),
|
||||
blockingReadDelay(sc_core::sc_time(
|
||||
config.BlockingReadDelay.value_or(DEFAULT_BLOCKING_READ_DELAY_NS), sc_core::SC_NS)),
|
||||
blockingWriteDelay(sc_core::sc_time(
|
||||
config.BlockingWriteDelay.value_or(DEFAULT_BLOCKING_WRITE_DELAY_NS), sc_core::SC_NS))
|
||||
|
||||
{
|
||||
if (pagePolicy == Config::PagePolicyType::Invalid)
|
||||
SC_REPORT_FATAL("McConfig", "Invalid PagePolicy");
|
||||
|
||||
if (scheduler == Config::SchedulerType::Invalid)
|
||||
SC_REPORT_FATAL("McConfig", "Invalid Scheduler");
|
||||
|
||||
if (schedulerBuffer == Config::SchedulerBufferType::Invalid)
|
||||
SC_REPORT_FATAL("McConfig", "Invalid SchedulerBuffer");
|
||||
|
||||
if (cmdMux == Config::CmdMuxType::Invalid)
|
||||
SC_REPORT_FATAL("McConfig", "Invalid CmdMux");
|
||||
|
||||
if (respQueue == Config::RespQueueType::Invalid)
|
||||
SC_REPORT_FATAL("McConfig", "Invalid RespQueue");
|
||||
|
||||
if (refreshPolicy == Config::RefreshPolicyType::Invalid)
|
||||
SC_REPORT_FATAL("McConfig", "Invalid RefreshPolicy");
|
||||
|
||||
if (powerDownPolicy == Config::PowerDownPolicyType::Invalid)
|
||||
SC_REPORT_FATAL("Configuration", "Invalid PowerDownPolicy");
|
||||
|
||||
if (arbiter == Config::ArbiterType::Invalid)
|
||||
SC_REPORT_FATAL("Arbiter", "Invalid Arbiter");
|
||||
|
||||
if (requestBufferSize < 1)
|
||||
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
|
||||
|
||||
if (requestBufferSizeRead < 1)
|
||||
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
|
||||
|
||||
if (requestBufferSizeWrite < 1)
|
||||
SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!");
|
||||
|
||||
arbitrationDelayFw = std::round(arbitrationDelayFw / memSpec.tCK) * memSpec.tCK;
|
||||
arbitrationDelayBw = std::round(arbitrationDelayBw / memSpec.tCK) * memSpec.tCK;
|
||||
|
||||
thinkDelayFw = std::round(thinkDelayFw / memSpec.tCK) * memSpec.tCK;
|
||||
thinkDelayBw = std::round(thinkDelayBw / memSpec.tCK) * memSpec.tCK;
|
||||
|
||||
phyDelayFw = std::round(phyDelayFw / memSpec.tCK) * memSpec.tCK;
|
||||
phyDelayBw = std::round(phyDelayBw / memSpec.tCK) * memSpec.tCK;
|
||||
|
||||
blockingReadDelay = std::round(blockingReadDelay / memSpec.tCK) * memSpec.tCK;
|
||||
blockingWriteDelay = std::round(blockingWriteDelay / memSpec.tCK) * memSpec.tCK;
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
115
src/libdramsys/DRAMSys/controller/McConfig.h
Normal file
115
src/libdramsys/DRAMSys/controller/McConfig.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2024, RPTU Kaiserslautern-Landau
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#ifndef MC_CONFIG_H
|
||||
#define MC_CONFIG_H
|
||||
|
||||
#include <DRAMSys/config/McConfig.h>
|
||||
#include <DRAMSys/configuration/memspec/MemSpec.h>
|
||||
|
||||
#include <systemc>
|
||||
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
struct McConfig
|
||||
{
|
||||
McConfig(const Config::McConfig& config, const MemSpec& memSpec);
|
||||
|
||||
Config::PagePolicyType pagePolicy;
|
||||
Config::SchedulerType scheduler;
|
||||
Config::SchedulerBufferType schedulerBuffer;
|
||||
|
||||
unsigned int lowWatermark;
|
||||
unsigned int highWatermark;
|
||||
|
||||
Config::CmdMuxType cmdMux;
|
||||
Config::RespQueueType respQueue;
|
||||
Config::ArbiterType arbiter;
|
||||
|
||||
unsigned int requestBufferSize;
|
||||
unsigned int requestBufferSizeRead;
|
||||
unsigned int requestBufferSizeWrite;
|
||||
|
||||
Config::RefreshPolicyType refreshPolicy;
|
||||
unsigned int refreshMaxPostponed;
|
||||
unsigned int refreshMaxPulledin;
|
||||
|
||||
Config::PowerDownPolicyType powerDownPolicy;
|
||||
unsigned int maxActiveTransactions;
|
||||
bool refreshManagement;
|
||||
|
||||
sc_core::sc_time arbitrationDelayFw;
|
||||
sc_core::sc_time arbitrationDelayBw;
|
||||
sc_core::sc_time thinkDelayFw;
|
||||
sc_core::sc_time thinkDelayBw;
|
||||
sc_core::sc_time phyDelayFw;
|
||||
sc_core::sc_time phyDelayBw;
|
||||
sc_core::sc_time blockingReadDelay;
|
||||
sc_core::sc_time blockingWriteDelay;
|
||||
|
||||
static constexpr Config::PagePolicyType DEFAULT_PAGE_POLICY = Config::PagePolicyType::Open;
|
||||
static constexpr Config::SchedulerType DEFAULT_SCHEDULER = Config::SchedulerType::FrFcfs;
|
||||
static constexpr Config::SchedulerBufferType DEFAULT_SCHEDULER_BUFFER =
|
||||
Config::SchedulerBufferType::Bankwise;
|
||||
static constexpr unsigned int DEFAULT_LOW_WATERMARK = 0;
|
||||
static constexpr unsigned int DEFAULT_HIGH_WATERMARK = 0;
|
||||
static constexpr Config::CmdMuxType DEFAULT_CMD_MUX = Config::CmdMuxType::Oldest;
|
||||
static constexpr Config::RespQueueType DEFAULT_RESP_QUEUE = Config::RespQueueType::Fifo;
|
||||
static constexpr Config::ArbiterType DEFAULT_ARBITER = Config::ArbiterType::Simple;
|
||||
static constexpr unsigned int DEFAULT_REQUEST_BUFFER_SIZE = 8;
|
||||
static constexpr unsigned int DEFAULT_REQUEST_BUFFER_SIZE_READ = 8;
|
||||
static constexpr unsigned int DEFAULT_REQUEST_BUFFER_SIZE_WRITE = 8;
|
||||
static constexpr Config::RefreshPolicyType DEFAULT_REFRESH_POLICY =
|
||||
Config::RefreshPolicyType::AllBank;
|
||||
static constexpr unsigned int DEFAULT_REFRESH_MAX_POSTPONED = 0;
|
||||
static constexpr unsigned int DEFAULT_REFRESH_MAX_PULLEDIN = 0;
|
||||
static constexpr Config::PowerDownPolicyType DEFAULT_POWER_DOWN_POLICY =
|
||||
Config::PowerDownPolicyType::NoPowerDown;
|
||||
static constexpr unsigned int DEFAULT_MAX_ACTIVE_TRANSACTIONS = 64;
|
||||
static constexpr bool DEFAULT_REFRESH_MANAGEMENT = false;
|
||||
static constexpr unsigned DEFAULT_ARBITRATION_DELAY_FW_NS = 0;
|
||||
static constexpr unsigned DEFAULT_ARBITRATION_DELAY_BW_NS = 0;
|
||||
static constexpr unsigned DEFAULT_THINK_DELAY_FW_NS = 0;
|
||||
static constexpr unsigned DEFAULT_THINK_DELAY_BW_NS = 0;
|
||||
static constexpr unsigned DEFAULT_PHY_DELAY_FW_NS = 0;
|
||||
static constexpr unsigned DEFAULT_PHY_DELAY_BW_NS = 0;
|
||||
static constexpr unsigned DEFAULT_BLOCKING_READ_DELAY_NS = 60;
|
||||
static constexpr unsigned DEFAULT_BLOCKING_WRITE_DELAY_NS = 60;
|
||||
};
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
#endif
|
||||
@@ -44,31 +44,28 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
CheckerDDR3::CheckerDDR3(const Configuration& config) :
|
||||
memSpec(dynamic_cast<const MemSpecDDR3*>(config.memSpec.get()))
|
||||
CheckerDDR3::CheckerDDR3(const MemSpecDDR3& memSpec) :
|
||||
memSpec(memSpec)
|
||||
{
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerDDR3", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
ControllerVector<Bank, sc_time>(memSpec.banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
ControllerVector<Rank, sc_time>(memSpec.ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL;
|
||||
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL;
|
||||
tWRRD = memSpec->tWL + tBURST + memSpec->tWTR - memSpec->tAL;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK;
|
||||
tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR + memSpec->tCK;
|
||||
tBURST = memSpec.defaultBurstLength / memSpec.dataRate * memSpec.tCK;
|
||||
tRDWR = memSpec.tRL + tBURST + 2 * memSpec.tCK - memSpec.tWL;
|
||||
tRDWR_R = memSpec.tRL + tBURST + memSpec.tRTRS - memSpec.tWL;
|
||||
tWRRD = memSpec.tWL + tBURST + memSpec.tWTR - memSpec.tAL;
|
||||
tWRRD_R = memSpec.tWL + tBURST + memSpec.tRTRS - memSpec.tRL;
|
||||
tWRPRE = memSpec.tWL + tBURST + memSpec.tWR;
|
||||
tRDPDEN = memSpec.tRL + tBURST + memSpec.tCK;
|
||||
tWRPDEN = memSpec.tWL + tBURST + memSpec.tWR;
|
||||
tWRAPDEN = memSpec.tWL + tBURST + memSpec.tWR + memSpec.tCK;
|
||||
}
|
||||
|
||||
sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
@@ -87,11 +84,11 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCD - memSpec.tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank]
|
||||
@@ -99,11 +96,11 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] !=
|
||||
lastScheduledByCommandAndRank[Command::RDA][rank]
|
||||
@@ -111,14 +108,14 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL);
|
||||
earliestTimeToStart, lastCommandStart + tWRPRE - memSpec.tRTP - memSpec.tAL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
@@ -139,11 +136,11 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSDLL);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
|
||||
command == Command::MWRA)
|
||||
@@ -153,7 +150,7 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCD - memSpec.tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -179,7 +176,7 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank]
|
||||
@@ -187,11 +184,11 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] !=
|
||||
lastScheduledByCommandAndRank[Command::WRA][rank]
|
||||
@@ -199,75 +196,75 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSDLL);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
||||
lastCommandStart + memSpec.tAL + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tAL + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -275,23 +272,23 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tAL + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tAL + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -303,51 +300,51 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
||||
lastCommandStart + memSpec.tAL + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tACTPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -368,17 +365,17 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
@@ -397,80 +394,80 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tREFPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart,
|
||||
lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
|
||||
lastCommandStart + std::max(tRDPDEN, memSpec.tAL + memSpec.tRTP + memSpec.tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
|
||||
earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec.tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKESR);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerDDR3", "Unknown command!");
|
||||
|
||||
if (lastCommandOnBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec.tCK);
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#ifndef CHECKERDDR3_H
|
||||
#define CHECKERDDR3_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecDDR3.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
|
||||
@@ -48,14 +47,14 @@ namespace DRAMSys
|
||||
class CheckerDDR3 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
explicit CheckerDDR3(const Configuration& config);
|
||||
explicit CheckerDDR3(const MemSpecDDR3 &memSpec);
|
||||
[[nodiscard]] 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;
|
||||
|
||||
private:
|
||||
const MemSpecDDR3* memSpec;
|
||||
const MemSpecDDR3& memSpec;
|
||||
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "CheckerDDR4.h"
|
||||
|
||||
#include "DRAMSys/common/DebugManager.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecDDR4.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -44,35 +45,32 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
CheckerDDR4::CheckerDDR4(const Configuration& config) :
|
||||
memSpec(dynamic_cast<const MemSpecDDR4*>(config.memSpec.get()))
|
||||
CheckerDDR4::CheckerDDR4(const MemSpecDDR4 &memSpec) :
|
||||
memSpec(memSpec)
|
||||
{
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerDDR4", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
ControllerVector<Bank, sc_time>(memSpec.banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<BankGroup, sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
ControllerVector<BankGroup, sc_time>(memSpec.bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
ControllerVector<Rank, sc_time>(memSpec.ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + tBURST + memSpec->tCK - memSpec->tWL + memSpec->tWPRE;
|
||||
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL + memSpec->tWPRE;
|
||||
tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S - memSpec->tAL;
|
||||
tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTR_L - memSpec->tAL;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL + memSpec->tRPRE;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK;
|
||||
tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR;
|
||||
tBURST = memSpec.defaultBurstLength / memSpec.dataRate * memSpec.tCK;
|
||||
tRDWR = memSpec.tRL + tBURST + memSpec.tCK - memSpec.tWL + memSpec.tWPRE;
|
||||
tRDWR_R = memSpec.tRL + tBURST + memSpec.tRTRS - memSpec.tWL + memSpec.tWPRE;
|
||||
tWRRD_S = memSpec.tWL + tBURST + memSpec.tWTR_S - memSpec.tAL;
|
||||
tWRRD_L = memSpec.tWL + tBURST + memSpec.tWTR_L - memSpec.tAL;
|
||||
tWRRD_R = memSpec.tWL + tBURST + memSpec.tRTRS - memSpec.tRL + memSpec.tRPRE;
|
||||
tWRPRE = memSpec.tWL + tBURST + memSpec.tWR;
|
||||
tRDPDEN = memSpec.tRL + tBURST + memSpec.tCK;
|
||||
tWRPDEN = memSpec.tWL + tBURST + memSpec.tWR;
|
||||
tWRAPDEN = memSpec.tWL + tBURST + memSpec.tCK + memSpec.tWR;
|
||||
}
|
||||
|
||||
sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
@@ -92,15 +90,15 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCD - memSpec.tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD_S);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank]
|
||||
@@ -108,15 +106,15 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] !=
|
||||
lastScheduledByCommandAndRank[Command::RDA][rank]
|
||||
@@ -124,14 +122,14 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL);
|
||||
earliestTimeToStart, lastCommandStart + tWRPRE - memSpec.tRTP - memSpec.tAL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
@@ -160,11 +158,11 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSDLL);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
|
||||
command == Command::MWRA)
|
||||
@@ -174,7 +172,7 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCD - memSpec.tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -200,11 +198,11 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD_S);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank]
|
||||
@@ -212,15 +210,15 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_L);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD_S);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] !=
|
||||
lastScheduledByCommandAndRank[Command::WRA][rank]
|
||||
@@ -228,79 +226,79 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSDLL);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_L);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRD_L);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD_S);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRD_S);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
||||
lastCommandStart + memSpec.tAL + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tAL + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -308,23 +306,23 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tAL + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tAL + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -336,51 +334,51 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
||||
lastCommandStart + memSpec.tAL + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tACTPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -401,17 +399,17 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
@@ -430,80 +428,80 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tREFPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart,
|
||||
lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
|
||||
lastCommandStart + std::max(tRDPDEN, memSpec.tAL + memSpec.tRTP + memSpec.tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
|
||||
earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec.tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKESR);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerDDR4", "Unknown command!");
|
||||
|
||||
if (lastCommandOnBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec.tCK);
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#ifndef CHECKERDDR4_H
|
||||
#define CHECKERDDR4_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecDDR4.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
|
||||
@@ -50,14 +49,14 @@ namespace DRAMSys
|
||||
class CheckerDDR4 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
explicit CheckerDDR4(const Configuration& config);
|
||||
explicit CheckerDDR4(const MemSpecDDR4& memSpec);
|
||||
[[nodiscard]] 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;
|
||||
|
||||
private:
|
||||
const MemSpecDDR4* memSpec;
|
||||
const MemSpecDDR4& memSpec;
|
||||
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "CheckerGDDR5.h"
|
||||
|
||||
#include "DRAMSys/common/DebugManager.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecGDDR5.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -44,36 +45,33 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
CheckerGDDR5::CheckerGDDR5(const Configuration& config) :
|
||||
memSpec(dynamic_cast<const MemSpecGDDR5*>(config.memSpec.get()))
|
||||
CheckerGDDR5::CheckerGDDR5(const MemSpecGDDR5& memSpec) :
|
||||
memSpec(memSpec)
|
||||
{
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerGDDR5", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
ControllerVector<Bank, sc_time>(memSpec.banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<BankGroup, sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
ControllerVector<BankGroup, sc_time>(memSpec.bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
ControllerVector<Rank, sc_time>(memSpec.ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last32Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||
last32Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec->ranksPerChannel);
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec.ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDSRE = memSpec->tCL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQO + tBURST;
|
||||
tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQI + tBURST;
|
||||
tRDWR_R = memSpec->tCL + tBURST + memSpec->tRTRS - memSpec->tWL;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tCL;
|
||||
tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTRS;
|
||||
tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTRL;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tBURST = memSpec.defaultBurstLength / memSpec.dataRate * memSpec.tCK;
|
||||
tRDSRE = memSpec.tCL + memSpec.tWCK2CKPIN + memSpec.tWCK2CK + memSpec.tWCK2DQO + tBURST;
|
||||
tWRSRE = memSpec.tWL + memSpec.tWCK2CKPIN + memSpec.tWCK2CK + memSpec.tWCK2DQI + tBURST;
|
||||
tRDWR_R = memSpec.tCL + tBURST + memSpec.tRTRS - memSpec.tWL;
|
||||
tWRRD_R = memSpec.tWL + tBURST + memSpec.tRTRS - memSpec.tCL;
|
||||
tWRRD_S = memSpec.tWL + tBURST + memSpec.tWTRS;
|
||||
tWRRD_L = memSpec.tWL + tBURST + memSpec.tWTRL;
|
||||
tWRPRE = memSpec.tWL + tBURST + memSpec.tWR;
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
@@ -92,15 +90,15 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCDRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank]
|
||||
@@ -108,15 +106,15 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] !=
|
||||
lastScheduledByCommandAndRank[Command::RDA][rank]
|
||||
@@ -124,14 +122,14 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec.tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
@@ -166,11 +164,11 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tLK);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -178,11 +176,11 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTW);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank]
|
||||
@@ -193,7 +191,7 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] !=
|
||||
lastScheduledByCommandAndRank[Command::RDA][rank]
|
||||
@@ -204,11 +202,11 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank]
|
||||
@@ -216,15 +214,15 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] !=
|
||||
lastScheduledByCommandAndRank[Command::WRA][rank]
|
||||
@@ -232,89 +230,89 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tLK);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW);
|
||||
|
||||
if (last32Activates[rank].size() >= 32)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last32Activates[rank].front() + memSpec->t32AW);
|
||||
std::max(earliestTimeToStart, last32Activates[rank].front() + memSpec.t32AW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -322,25 +320,25 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXPN);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -352,126 +350,126 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCPB);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (bankwiseRefreshCounter[rank] == 0)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCPB);
|
||||
else
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRREFD);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW);
|
||||
|
||||
if (last32Activates[rank].size() >= 32)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last32Activates[rank].front() + memSpec->t32AW);
|
||||
std::max(earliestTimeToStart, last32Activates[rank].front() + memSpec.t32AW);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
@@ -493,13 +491,13 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXPN);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
@@ -517,23 +515,23 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -543,49 +541,49 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command,
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE));
|
||||
lastCommandStart + std::max(memSpec.tRTP + memSpec.tRP, tRDSRE));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXPN);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXPN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerGDDR5", "Unknown command!");
|
||||
|
||||
// Check if command bus is free
|
||||
if (lastCommandOnBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec.tCK);
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
@@ -618,7 +616,7 @@ void CheckerGDDR5::insert(Command command, const tlm_generic_payload& payload)
|
||||
}
|
||||
|
||||
if (command == Command::REFPB)
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec->banksPerRank;
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec.banksPerRank;
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#ifndef CHECKERGDDR5_H
|
||||
#define CHECKERGDDR5_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecGDDR5.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
|
||||
@@ -48,14 +47,14 @@ namespace DRAMSys
|
||||
class CheckerGDDR5 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
explicit CheckerGDDR5(const Configuration& config);
|
||||
explicit CheckerGDDR5(const MemSpecGDDR5& memSpec);
|
||||
[[nodiscard]] 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;
|
||||
|
||||
private:
|
||||
const MemSpecGDDR5* memSpec;
|
||||
const MemSpecGDDR5& memSpec;
|
||||
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
|
||||
@@ -44,36 +44,33 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
CheckerGDDR5X::CheckerGDDR5X(const Configuration& config) :
|
||||
memSpec(dynamic_cast<const MemSpecGDDR5X*>(config.memSpec.get()))
|
||||
CheckerGDDR5X::CheckerGDDR5X(const MemSpecGDDR5X& memSpec) :
|
||||
memSpec(memSpec)
|
||||
{
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerGDDR5X", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
ControllerVector<Bank, sc_time>(memSpec.banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<BankGroup, sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
ControllerVector<BankGroup, sc_time>(memSpec.bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
ControllerVector<Rank, sc_time>(memSpec.ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last32Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||
last32Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec->ranksPerChannel);
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec.ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQO + tBURST;
|
||||
tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQI + tBURST;
|
||||
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL;
|
||||
tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTRS;
|
||||
tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTRL;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tBURST = memSpec.defaultBurstLength / memSpec.dataRate * memSpec.tCK;
|
||||
tRDSRE = memSpec.tRL + memSpec.tWCK2CKPIN + memSpec.tWCK2CK + memSpec.tWCK2DQO + tBURST;
|
||||
tWRSRE = memSpec.tWL + memSpec.tWCK2CKPIN + memSpec.tWCK2CK + memSpec.tWCK2DQI + tBURST;
|
||||
tRDWR_R = memSpec.tRL + tBURST + memSpec.tRTRS - memSpec.tWL;
|
||||
tWRRD_R = memSpec.tWL + tBURST + memSpec.tRTRS - memSpec.tRL;
|
||||
tWRRD_S = memSpec.tWL + tBURST + memSpec.tWTRS;
|
||||
tWRRD_L = memSpec.tWL + tBURST + memSpec.tWTRL;
|
||||
tWRPRE = memSpec.tWL + tBURST + memSpec.tWR;
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
@@ -89,20 +86,20 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
unsigned burstLength = ControllerExtension::getBurstLength(payload);
|
||||
assert(!(memSpec->dataRate == 4) || (burstLength == 8)); // DDR mode (QDR wrt CK)
|
||||
assert(!(memSpec->dataRate == 8) || (burstLength == 16)); // QDR mode (ODR wrt CK)
|
||||
assert(!(memSpec.dataRate == 4) || (burstLength == 8)); // DDR mode (QDR wrt CK)
|
||||
assert(!(memSpec.dataRate == 8) || (burstLength == 16)); // QDR mode (ODR wrt CK)
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCDRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank]
|
||||
@@ -110,15 +107,15 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] !=
|
||||
lastScheduledByCommandAndRank[Command::RDA][rank]
|
||||
@@ -126,14 +123,14 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec.tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
@@ -168,25 +165,25 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tLK);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
unsigned burstLength = ControllerExtension::getBurstLength(payload);
|
||||
assert(!(memSpec->dataRate == 4) || (burstLength == 8)); // DDR mode (QDR wrt CK)
|
||||
assert(!(memSpec->dataRate == 8) || (burstLength == 16)); // QDR mode (ODR wrt CK)
|
||||
assert(!(memSpec.dataRate == 4) || (burstLength == 8)); // DDR mode (QDR wrt CK)
|
||||
assert(!(memSpec.dataRate == 8) || (burstLength == 16)); // QDR mode (ODR wrt CK)
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTW);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank]
|
||||
@@ -197,7 +194,7 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] !=
|
||||
lastScheduledByCommandAndRank[Command::RDA][rank]
|
||||
@@ -208,11 +205,11 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank]
|
||||
@@ -220,15 +217,15 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] !=
|
||||
lastScheduledByCommandAndRank[Command::WRA][rank]
|
||||
@@ -236,89 +233,89 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tLK);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW);
|
||||
|
||||
if (last32Activates[rank].size() >= 32)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last32Activates[rank].front() + memSpec->t32AW);
|
||||
std::max(earliestTimeToStart, last32Activates[rank].front() + memSpec.t32AW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -326,25 +323,25 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -356,126 +353,126 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCPB);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (bankwiseRefreshCounter[rank] == 0)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCPB);
|
||||
else
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRREFD);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW);
|
||||
|
||||
if (last32Activates[rank].size() >= 32)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last32Activates[rank].front() + memSpec->t32AW);
|
||||
std::max(earliestTimeToStart, last32Activates[rank].front() + memSpec.t32AW);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
@@ -497,13 +494,13 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
@@ -521,23 +518,23 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -547,49 +544,49 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command,
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE));
|
||||
lastCommandStart + std::max(memSpec.tRTP + memSpec.tRP, tRDSRE));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCPB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCPB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerGDDR5X", "Unknown command!");
|
||||
|
||||
// Check if command bus is free
|
||||
if (lastCommandOnBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec.tCK);
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
@@ -622,7 +619,7 @@ void CheckerGDDR5X::insert(Command command, const tlm_generic_payload& payload)
|
||||
}
|
||||
|
||||
if (command == Command::REFPB)
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec->banksPerRank;
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec.banksPerRank;
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#ifndef CHECKERGDDR5X_H
|
||||
#define CHECKERGDDR5X_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecGDDR5X.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
|
||||
@@ -48,14 +47,14 @@ namespace DRAMSys
|
||||
class CheckerGDDR5X final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
explicit CheckerGDDR5X(const Configuration& config);
|
||||
explicit CheckerGDDR5X(const MemSpecGDDR5X& memSpec);
|
||||
[[nodiscard]] 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;
|
||||
|
||||
private:
|
||||
const MemSpecGDDR5X* memSpec;
|
||||
const MemSpecGDDR5X& memSpec;
|
||||
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
|
||||
@@ -44,35 +44,32 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
CheckerGDDR6::CheckerGDDR6(const Configuration& config) :
|
||||
memSpec(dynamic_cast<const MemSpecGDDR6*>(config.memSpec.get()))
|
||||
CheckerGDDR6::CheckerGDDR6(const MemSpecGDDR6& memSpec) :
|
||||
memSpec(memSpec)
|
||||
{
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerGDDR6", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
ControllerVector<Bank, sc_time>(memSpec.banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<BankGroup, sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
ControllerVector<BankGroup, sc_time>(memSpec.bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
ControllerVector<Rank, sc_time>(memSpec.ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec->ranksPerChannel);
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec.ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQO + tBURST;
|
||||
tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQI + tBURST;
|
||||
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL;
|
||||
tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTRS;
|
||||
tWRRD_L = memSpec->tWL + tBURST + memSpec->tWTRL;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tBURST = memSpec.defaultBurstLength / memSpec.dataRate * memSpec.tCK;
|
||||
tRDSRE = memSpec.tRL + memSpec.tWCK2CKPIN + memSpec.tWCK2CK + memSpec.tWCK2DQO + tBURST;
|
||||
tWRSRE = memSpec.tWL + memSpec.tWCK2CKPIN + memSpec.tWCK2CK + memSpec.tWCK2DQI + tBURST;
|
||||
tRDWR_R = memSpec.tRL + tBURST + memSpec.tRTRS - memSpec.tWL;
|
||||
tWRRD_R = memSpec.tWL + tBURST + memSpec.tRTRS - memSpec.tRL;
|
||||
tWRRD_S = memSpec.tWL + tBURST + memSpec.tWTRS;
|
||||
tWRRD_L = memSpec.tWL + tBURST + memSpec.tWTRL;
|
||||
tWRPRE = memSpec.tWL + tBURST + memSpec.tWR;
|
||||
}
|
||||
|
||||
sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
@@ -91,15 +88,15 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCDRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank]
|
||||
@@ -107,15 +104,15 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] !=
|
||||
lastScheduledByCommandAndRank[Command::RDA][rank]
|
||||
@@ -123,14 +120,14 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec.tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
@@ -165,11 +162,11 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tLK);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA)
|
||||
{
|
||||
@@ -177,11 +174,11 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCDWR);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTW);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank]
|
||||
@@ -192,7 +189,7 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] !=
|
||||
lastScheduledByCommandAndRank[Command::RDA][rank]
|
||||
@@ -203,11 +200,11 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank]
|
||||
@@ -215,15 +212,15 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] !=
|
||||
lastScheduledByCommandAndRank[Command::WRA][rank]
|
||||
@@ -231,85 +228,85 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tLK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tLK);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRREFD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -317,25 +314,25 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -347,129 +344,129 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (bankwiseRefreshCounter[rank] == 0)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
else
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRREFD);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDE);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tACTPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -490,22 +487,22 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tPREPDE);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tPREPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDE);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tREFPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
@@ -524,42 +521,42 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tPREPDE);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tPREPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tPREPDE);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tPREPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDE);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tREFPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tREFPDE);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tREFPDE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -569,49 +566,49 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command,
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE));
|
||||
lastCommandStart + std::max(memSpec.tRTP + memSpec.tRP, tRDSRE));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKESR);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerGDDR6", "Unknown command!");
|
||||
|
||||
// Check if command bus is free
|
||||
if (lastCommandOnBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec.tCK);
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
@@ -640,7 +637,7 @@ void CheckerGDDR6::insert(Command command, const tlm_generic_payload& payload)
|
||||
}
|
||||
|
||||
if (command == Command::REFPB)
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec->banksPerRank;
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec.banksPerRank;
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#ifndef CHECKERGDDR6_H
|
||||
#define CHECKERGDDR6_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecGDDR6.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
|
||||
@@ -48,14 +47,14 @@ namespace DRAMSys
|
||||
class CheckerGDDR6 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
explicit CheckerGDDR6(const Configuration& config);
|
||||
explicit CheckerGDDR6(const MemSpecGDDR6 &memSpec);
|
||||
[[nodiscard]] 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;
|
||||
|
||||
private:
|
||||
const MemSpecGDDR6* memSpec;
|
||||
const MemSpecGDDR6& memSpec;
|
||||
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "CheckerHBM2.h"
|
||||
|
||||
#include "DRAMSys/common/DebugManager.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecHBM2.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -44,36 +45,33 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
CheckerHBM2::CheckerHBM2(const Configuration& config) :
|
||||
memSpec(dynamic_cast<const MemSpecHBM2*>(config.memSpec.get()))
|
||||
CheckerHBM2::CheckerHBM2(const MemSpecHBM2& memSpec) :
|
||||
memSpec(memSpec)
|
||||
{
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerHBM2", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
ControllerVector<Bank, sc_time>(memSpec.banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndBankGroup = std::vector<ControllerVector<BankGroup, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<BankGroup, sc_time>(memSpec->bankGroupsPerChannel, scMaxTime));
|
||||
ControllerVector<BankGroup, sc_time>(memSpec.bankGroupsPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
ControllerVector<Rank, sc_time>(memSpec.ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnRasBus = scMaxTime;
|
||||
lastCommandOnCasBus = scMaxTime;
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec->ranksPerChannel);
|
||||
bankwiseRefreshCounter = ControllerVector<Rank, unsigned>(memSpec.ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDPDE = memSpec->tRL + memSpec->tPL + tBURST + memSpec->tCK;
|
||||
tBURST = memSpec.defaultBurstLength / memSpec.dataRate * memSpec.tCK;
|
||||
tRDPDE = memSpec.tRL + memSpec.tPL + tBURST + memSpec.tCK;
|
||||
tRDSRE = tRDPDE;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tWRPDE = memSpec->tWL + memSpec->tPL + tBURST + memSpec->tCK + memSpec->tWR;
|
||||
tWRAPDE = memSpec->tWL + memSpec->tPL + tBURST + memSpec->tCK + memSpec->tWR;
|
||||
tWRRDS = memSpec->tWL + tBURST + memSpec->tWTRS;
|
||||
tWRRDL = memSpec->tWL + tBURST + memSpec->tWTRL;
|
||||
tWRPRE = memSpec.tWL + tBURST + memSpec.tWR;
|
||||
tWRPDE = memSpec.tWL + memSpec.tPL + tBURST + memSpec.tCK + memSpec.tWR;
|
||||
tWRAPDE = memSpec.tWL + memSpec.tPL + tBURST + memSpec.tCK + memSpec.tWR;
|
||||
tWRRDS = memSpec.tWL + tBURST + memSpec.tWTRS;
|
||||
tWRRDL = memSpec.tWL + tBURST + memSpec.tWTRL;
|
||||
}
|
||||
|
||||
sc_time CheckerHBM2::timeToSatisfyConstraints(Command command,
|
||||
@@ -89,37 +87,37 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command,
|
||||
if (command == Command::RD || command == Command::RDA)
|
||||
{
|
||||
unsigned burstLength = ControllerExtension::getBurstLength(payload);
|
||||
assert(!(memSpec->ranksPerChannel == 1) ||
|
||||
assert(!(memSpec.ranksPerChannel == 1) ||
|
||||
(burstLength == 2 || burstLength == 4)); // Legacy mode
|
||||
assert(!(memSpec->ranksPerChannel == 2) || (burstLength == 4)); // Pseudo-channel mode
|
||||
assert(!(memSpec.ranksPerChannel == 2) || (burstLength == 4)); // Pseudo-channel mode
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD + memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCDRD + memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RD][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::RDA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE - memSpec.tRTP);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
@@ -140,128 +138,128 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
|
||||
command == Command::MWRA)
|
||||
{
|
||||
unsigned burstLength = ControllerExtension::getBurstLength(payload);
|
||||
assert(!(memSpec->ranksPerChannel == 1) ||
|
||||
assert(!(memSpec.ranksPerChannel == 1) ||
|
||||
(burstLength == 2 || burstLength == 4)); // Legacy mode
|
||||
assert(!(memSpec->ranksPerChannel == 2) || (burstLength == 4)); // Pseudo-channel mode
|
||||
assert(!(memSpec.ranksPerChannel == 2) || (burstLength == 4)); // Pseudo-channel mode
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR + memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCDWR + memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTW);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTW);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WR][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::WRA][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
lastCommandStart + memSpec->tRTP + memSpec->tRP - memSpec->tCK);
|
||||
lastCommandStart + memSpec.tRTP + memSpec.tRP - memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart,
|
||||
lastCommandStart + tWRPRE + memSpec->tRP - memSpec->tCK);
|
||||
lastCommandStart + tWRPRE + memSpec.tRP - memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP - memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP - memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP - memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP - memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP - memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXP];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP - memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP - memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC - memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC - memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB - memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCSB - memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD - memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRREFD - memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS - memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS - memSpec.tCK);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW - memSpec->tCK);
|
||||
earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW - memSpec.tCK);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS + memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -269,22 +267,22 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS + memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -296,122 +294,122 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCSB);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC + memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXP];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCSB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC + memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBankGroup[Command::ACT][bankGroup];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDL + memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDL + memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRDS + memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRDS + memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRTP + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXP];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCSB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
{
|
||||
if (bankwiseRefreshCounter[rank] == 0)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCSB);
|
||||
else
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRREFD);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRREFD);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
@@ -433,13 +431,13 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDEA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
@@ -457,65 +455,65 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXP];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDEP];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::ACT];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC + memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC + memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
lastCommandStart + std::max(memSpec->tRTP + memSpec->tRP, tRDSRE));
|
||||
lastCommandStart + std::max(memSpec.tRTP + memSpec.tRP, tRDSRE));
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PREPB];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PREAB];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::PDXP];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::REFAB];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::REFPB];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCSB);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCSB);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEX];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommand[Command::SREFEN];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKESR);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerHBM2", "Unknown command!");
|
||||
@@ -523,12 +521,12 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command,
|
||||
if (command.isRasCommand())
|
||||
{
|
||||
if (lastCommandOnRasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnRasBus + memSpec.tCK);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lastCommandOnCasBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnCasBus + memSpec.tCK);
|
||||
}
|
||||
|
||||
return earliestTimeToStart;
|
||||
@@ -558,7 +556,7 @@ void CheckerHBM2::insert(Command command, const tlm_generic_payload& payload)
|
||||
if (command.isCasCommand())
|
||||
lastCommandOnCasBus = sc_time_stamp();
|
||||
else if (command == Command::ACT)
|
||||
lastCommandOnRasBus = sc_time_stamp() + memSpec->tCK;
|
||||
lastCommandOnRasBus = sc_time_stamp() + memSpec.tCK;
|
||||
else
|
||||
lastCommandOnRasBus = sc_time_stamp();
|
||||
|
||||
@@ -570,7 +568,7 @@ void CheckerHBM2::insert(Command command, const tlm_generic_payload& payload)
|
||||
}
|
||||
|
||||
if (command == Command::REFPB)
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec->banksPerRank;
|
||||
bankwiseRefreshCounter[rank] = (bankwiseRefreshCounter[rank] + 1) % memSpec.banksPerRank;
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#ifndef CHECKERHBM2_H
|
||||
#define CHECKERHBM2_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecHBM2.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
|
||||
@@ -48,14 +47,14 @@ namespace DRAMSys
|
||||
class CheckerHBM2 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
explicit CheckerHBM2(const Configuration& config);
|
||||
explicit CheckerHBM2(const MemSpecHBM2& memSpec);
|
||||
[[nodiscard]] 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;
|
||||
|
||||
private:
|
||||
const MemSpecHBM2* memSpec;
|
||||
const MemSpecHBM2& memSpec;
|
||||
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<BankGroup, sc_core::sc_time>> lastScheduledByCommandAndBankGroup;
|
||||
|
||||
@@ -44,49 +44,46 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
CheckerLPDDR4::CheckerLPDDR4(const Configuration& config) :
|
||||
memSpec(dynamic_cast<const MemSpecLPDDR4*>(config.memSpec.get()))
|
||||
CheckerLPDDR4::CheckerLPDDR4(const MemSpecLPDDR4& memSpec) :
|
||||
memSpec(memSpec)
|
||||
{
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerLPDDR4", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
ControllerVector<Bank, sc_time>(memSpec.banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
ControllerVector<Rank, sc_time>(memSpec.ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||
|
||||
lastBurstLengthByCommandAndBank = ControllerVector<Command, ControllerVector<Bank, uint8_t>>(
|
||||
Command::WRA + 1, ControllerVector<Bank, uint8_t>(memSpec->banksPerChannel));
|
||||
Command::WRA + 1, ControllerVector<Bank, uint8_t>(memSpec.banksPerChannel));
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tBURST = memSpec.defaultBurstLength / memSpec.dataRate * memSpec.tCK;
|
||||
tRDWR =
|
||||
memSpec->tRL + memSpec->tDQSCK + tBURST - memSpec->tWL + memSpec->tWPRE + memSpec->tRPST;
|
||||
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL;
|
||||
tWRRD = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tWTR;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL;
|
||||
tRDPRE = memSpec->tRTP + tBURST - 6 * memSpec->tCK;
|
||||
tRDAACT = memSpec->tRTP + tBURST - 8 * memSpec->tCK + memSpec->tRPpb;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR + 2 * memSpec->tCK;
|
||||
tWRAACT = memSpec->tWL + tBURST + memSpec->tCK + memSpec->tWR + memSpec->tRPpb;
|
||||
tACTPDEN = 3 * memSpec->tCK + memSpec->tCMDCKE;
|
||||
tPRPDEN = memSpec->tCK + memSpec->tCMDCKE;
|
||||
tRDPDEN = 3 * memSpec->tCK + memSpec->tRL + memSpec->tDQSCK + tBURST + memSpec->tRPST;
|
||||
memSpec.tRL + memSpec.tDQSCK + tBURST - memSpec.tWL + memSpec.tWPRE + memSpec.tRPST;
|
||||
tRDWR_R = memSpec.tRL + tBURST + memSpec.tRTRS - memSpec.tWL;
|
||||
tWRRD = memSpec.tWL + memSpec.tCK + tBURST + memSpec.tWTR;
|
||||
tWRRD_R = memSpec.tWL + tBURST + memSpec.tRTRS - memSpec.tRL;
|
||||
tRDPRE = memSpec.tRTP + tBURST - 6 * memSpec.tCK;
|
||||
tRDAACT = memSpec.tRTP + tBURST - 8 * memSpec.tCK + memSpec.tRPpb;
|
||||
tWRPRE = memSpec.tWL + tBURST + memSpec.tCK + memSpec.tWR + 2 * memSpec.tCK;
|
||||
tWRAACT = memSpec.tWL + tBURST + memSpec.tCK + memSpec.tWR + memSpec.tRPpb;
|
||||
tACTPDEN = 3 * memSpec.tCK + memSpec.tCMDCKE;
|
||||
tPRPDEN = memSpec.tCK + memSpec.tCMDCKE;
|
||||
tRDPDEN = 3 * memSpec.tCK + memSpec.tRL + memSpec.tDQSCK + tBURST + memSpec.tRPST;
|
||||
tWRPDEN =
|
||||
3 * memSpec->tCK + memSpec->tWL +
|
||||
(std::ceil(memSpec->tDQSS / memSpec->tCK) + std::ceil(memSpec->tDQS2DQ / memSpec->tCK)) *
|
||||
memSpec->tCK +
|
||||
tBURST + memSpec->tWR;
|
||||
3 * memSpec.tCK + memSpec.tWL +
|
||||
(std::ceil(memSpec.tDQSS / memSpec.tCK) + std::ceil(memSpec.tDQS2DQ / memSpec.tCK)) *
|
||||
memSpec.tCK +
|
||||
tBURST + memSpec.tWR;
|
||||
tWRAPDEN =
|
||||
3 * memSpec->tCK + memSpec->tWL +
|
||||
(std::ceil(memSpec->tDQSS / memSpec->tCK) + std::ceil(memSpec->tDQS2DQ / memSpec->tCK)) *
|
||||
memSpec->tCK +
|
||||
tBURST + memSpec->tWR + 2 * memSpec->tCK;
|
||||
tREFPDEN = memSpec->tCK + memSpec->tCMDCKE;
|
||||
3 * memSpec.tCK + memSpec.tWL +
|
||||
(std::ceil(memSpec.tDQSS / memSpec.tCK) + std::ceil(memSpec.tDQS2DQ / memSpec.tCK)) *
|
||||
memSpec.tCK +
|
||||
tBURST + memSpec.tWR + 2 * memSpec.tCK;
|
||||
tREFPDEN = memSpec.tCK + memSpec.tCMDCKE;
|
||||
}
|
||||
|
||||
sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
@@ -102,11 +99,11 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
{
|
||||
unsigned burstLength = ControllerExtension::getBurstLength(payload);
|
||||
assert((burstLength == 16) || (burstLength == 32)); // TODO: BL16/32 OTF
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
assert(burstLength <= memSpec.maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -118,7 +115,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -130,7 +127,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
@@ -164,18 +161,18 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
|
||||
command == Command::MWRA)
|
||||
{
|
||||
unsigned burstLength = ControllerExtension::getBurstLength(payload);
|
||||
assert((burstLength == 16) || (burstLength == 32));
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
assert(burstLength <= memSpec.maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -209,7 +206,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -221,7 +218,7 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
if (command == Command::MWR || command == Command::MWRA)
|
||||
{
|
||||
@@ -230,36 +227,36 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::WR][bank] == 32)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, lastCommandStart + memSpec->tCCDMW + 8 * memSpec->tCK);
|
||||
earliestTimeToStart, lastCommandStart + memSpec.tCCDMW + 8 * memSpec.tCK);
|
||||
else
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDMW);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDMW);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
{
|
||||
if (lastBurstLengthByCommandAndBank[Command::WRA][bank] == 32)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, lastCommandStart + memSpec->tCCDMW + 8 * memSpec->tCK);
|
||||
earliestTimeToStart, lastCommandStart + memSpec.tCCDMW + 8 * memSpec.tCK);
|
||||
else
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCDMW);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCDMW);
|
||||
}
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -272,52 +269,52 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb - 2 * memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPpb - 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab - 2 * memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPab - 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart,
|
||||
lastCommandStart + memSpec->tRFCab - 2 * memSpec->tCK);
|
||||
lastCommandStart + memSpec.tRFCab - 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart,
|
||||
lastCommandStart + memSpec->tRFCpb - 2 * memSpec->tCK);
|
||||
lastCommandStart + memSpec.tRFCpb - 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD - 2 * memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRD - 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR - 2 * memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR - 2 * memSpec.tCK);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
last4Activates[rank].front() + memSpec->tFAW - 3 * memSpec->tCK);
|
||||
last4Activates[rank].front() + memSpec.tFAW - 3 * memSpec.tCK);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS + 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -329,18 +326,18 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS + 2 * memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS + 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -360,110 +357,110 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPPD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + 2 * memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCpb + 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + 2 * memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCpb + 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD + 2 * memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRD + 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW - memSpec->tCK);
|
||||
earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW - memSpec.tCK);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
@@ -497,13 +494,13 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
@@ -537,72 +534,72 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb + 2 * memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCpb + 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tRDPRE + memSpec->tRPpb));
|
||||
earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tRDPRE + memSpec.tRPpb));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRPpb));
|
||||
lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec.tRPpb));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tSR);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerLPDDR4", "Unknown command!");
|
||||
|
||||
// Check if command bus is free
|
||||
if (lastCommandOnBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec.tCK);
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
@@ -626,7 +623,7 @@ void CheckerLPDDR4::insert(Command command, const tlm_generic_payload& payload)
|
||||
lastScheduledByCommandAndRank[command][rank] = sc_time_stamp();
|
||||
lastScheduledByCommand[command] = sc_time_stamp();
|
||||
|
||||
lastCommandOnBus = sc_time_stamp() + memSpec->getCommandLength(command) - memSpec->tCK;
|
||||
lastCommandOnBus = sc_time_stamp() + memSpec.getCommandLength(command) - memSpec.tCK;
|
||||
|
||||
if (command == Command::ACT || command == Command::REFPB)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#ifndef CHECKERLPDDR4_H
|
||||
#define CHECKERLPDDR4_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecLPDDR4.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
|
||||
@@ -48,14 +47,14 @@ namespace DRAMSys
|
||||
class CheckerLPDDR4 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
explicit CheckerLPDDR4(const Configuration& config);
|
||||
explicit CheckerLPDDR4(const MemSpecLPDDR4& memSpec);
|
||||
[[nodiscard]] 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;
|
||||
|
||||
private:
|
||||
const MemSpecLPDDR4* memSpec;
|
||||
const MemSpecLPDDR4& memSpec;
|
||||
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
|
||||
@@ -44,31 +44,28 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
CheckerSTTMRAM::CheckerSTTMRAM(const Configuration& config) :
|
||||
memSpec(dynamic_cast<const MemSpecSTTMRAM*>(config.memSpec.get()))
|
||||
CheckerSTTMRAM::CheckerSTTMRAM(const MemSpecSTTMRAM& memSpec) :
|
||||
memSpec(memSpec)
|
||||
{
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerSTTMRAM", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
ControllerVector<Bank, sc_time>(memSpec.banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
ControllerVector<Rank, sc_time>(memSpec.ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL;
|
||||
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL;
|
||||
tWRRD = memSpec->tWL + tBURST + memSpec->tWTR - memSpec->tAL;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL;
|
||||
tWRPRE = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tRDPDEN = memSpec->tRL + tBURST + memSpec->tCK;
|
||||
tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR;
|
||||
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR + memSpec->tCK;
|
||||
tBURST = memSpec.defaultBurstLength / memSpec.dataRate * memSpec.tCK;
|
||||
tRDWR = memSpec.tRL + tBURST + 2 * memSpec.tCK - memSpec.tWL;
|
||||
tRDWR_R = memSpec.tRL + tBURST + memSpec.tRTRS - memSpec.tWL;
|
||||
tWRRD = memSpec.tWL + tBURST + memSpec.tWTR - memSpec.tAL;
|
||||
tWRRD_R = memSpec.tWL + tBURST + memSpec.tRTRS - memSpec.tRL;
|
||||
tWRPRE = memSpec.tWL + tBURST + memSpec.tWR;
|
||||
tRDPDEN = memSpec.tRL + tBURST + memSpec.tCK;
|
||||
tWRPDEN = memSpec.tWL + tBURST + memSpec.tWR;
|
||||
tWRAPDEN = memSpec.tWL + tBURST + memSpec.tWR + memSpec.tCK;
|
||||
}
|
||||
|
||||
sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
@@ -87,11 +84,11 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCD - memSpec.tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank]
|
||||
@@ -99,11 +96,11 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] !=
|
||||
lastScheduledByCommandAndRank[Command::RDA][rank]
|
||||
@@ -111,14 +108,14 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, lastCommandStart + tWRPRE - memSpec->tRTP - memSpec->tAL);
|
||||
earliestTimeToStart, lastCommandStart + tWRPRE - memSpec.tRTP - memSpec.tAL);
|
||||
}
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
@@ -139,11 +136,11 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSDLL);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
|
||||
command == Command::MWRA)
|
||||
@@ -153,7 +150,7 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCD - memSpec.tAL);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -179,7 +176,7 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank]
|
||||
@@ -187,11 +184,11 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] !=
|
||||
lastScheduledByCommandAndRank[Command::WRA][rank]
|
||||
@@ -199,71 +196,71 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSDLL);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSDLL);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
lastCommandStart + memSpec->tAL + memSpec->tRTP + memSpec->tRP);
|
||||
lastCommandStart + memSpec.tAL + memSpec.tRTP + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tAL + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WR][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -271,23 +268,23 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tAL + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tAL + memSpec->tRTP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tAL + memSpec.tRTP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -299,14 +296,14 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tACTPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tACTPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -327,17 +324,17 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
@@ -356,71 +353,71 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec->tPRPDEN);
|
||||
std::max(earliestTimeToStart, lastCommandStart + memSpec.tPRPDEN);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tPD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tPD);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart,
|
||||
lastCommandStart + std::max(tRDPDEN, memSpec->tAL + memSpec->tRTP + memSpec->tRP));
|
||||
lastCommandStart + std::max(tRDPDEN, memSpec.tAL + memSpec.tRTP + memSpec.tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
|
||||
earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec.tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXS);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKESR);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerSTTMRAM", "Unknown command!");
|
||||
|
||||
if (lastCommandOnBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec.tCK);
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#ifndef CHECKERSTTMRAM_H
|
||||
#define CHECKERSTTMRAM_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecSTTMRAM.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
|
||||
@@ -48,14 +47,14 @@ namespace DRAMSys
|
||||
class CheckerSTTMRAM final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
explicit CheckerSTTMRAM(const Configuration& config);
|
||||
explicit CheckerSTTMRAM(const MemSpecSTTMRAM& memSpec);
|
||||
[[nodiscard]] 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;
|
||||
|
||||
private:
|
||||
const MemSpecSTTMRAM* memSpec;
|
||||
const MemSpecSTTMRAM& memSpec;
|
||||
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
|
||||
@@ -44,31 +44,28 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
CheckerWideIO::CheckerWideIO(const Configuration& config) :
|
||||
memSpec(dynamic_cast<const MemSpecWideIO*>(config.memSpec.get()))
|
||||
CheckerWideIO::CheckerWideIO(const MemSpecWideIO& memSpec) :
|
||||
memSpec(memSpec)
|
||||
{
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerWideIO", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
ControllerVector<Bank, sc_time>(memSpec.banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
ControllerVector<Rank, sc_time>(memSpec.ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last2Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last2Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength * memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + tBURST + memSpec->tCK;
|
||||
tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL;
|
||||
tWRPRE = memSpec->tWL + tBURST - memSpec->tCK + memSpec->tWR;
|
||||
tWRRD = memSpec->tWL + tBURST - memSpec->tCK + memSpec->tWTR;
|
||||
tWRRD_R = memSpec->tWL + tBURST + memSpec->tRTRS - memSpec->tRL;
|
||||
tRDPDEN = memSpec->tRL + tBURST; // + memSpec->tCK; ??
|
||||
tWRPDEN = memSpec->tWL + tBURST + memSpec->tWR - memSpec->tCK;
|
||||
tWRAPDEN = memSpec->tWL + tBURST + memSpec->tWR; // + memSpec->tCK; ??
|
||||
tBURST = memSpec.defaultBurstLength * memSpec.tCK;
|
||||
tRDWR = memSpec.tRL + tBURST + memSpec.tCK;
|
||||
tRDWR_R = memSpec.tRL + tBURST + memSpec.tRTRS - memSpec.tWL;
|
||||
tWRPRE = memSpec.tWL + tBURST - memSpec.tCK + memSpec.tWR;
|
||||
tWRRD = memSpec.tWL + tBURST - memSpec.tCK + memSpec.tWTR;
|
||||
tWRRD_R = memSpec.tWL + tBURST + memSpec.tRTRS - memSpec.tRL;
|
||||
tRDPDEN = memSpec.tRL + tBURST; // + memSpec.tCK; ??
|
||||
tWRPDEN = memSpec.tWL + tBURST + memSpec.tWR - memSpec.tCK;
|
||||
tWRAPDEN = memSpec.tWL + tBURST + memSpec.tWR; // + memSpec.tCK; ??
|
||||
}
|
||||
|
||||
sc_time CheckerWideIO::timeToSatisfyConstraints(Command command,
|
||||
@@ -84,11 +81,11 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command,
|
||||
{
|
||||
unsigned burstLength = ControllerExtension::getBurstLength(payload);
|
||||
assert((burstLength == 2) || (burstLength == 4));
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
assert(burstLength <= memSpec.maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -100,7 +97,7 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -112,7 +109,7 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
@@ -146,18 +143,18 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
|
||||
command == Command::MWRA)
|
||||
{
|
||||
unsigned burstLength = ControllerExtension::getBurstLength(payload);
|
||||
assert((burstLength == 2) || (burstLength == 4));
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
assert(burstLength <= memSpec.maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -191,7 +188,7 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -203,65 +200,65 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
|
||||
if (last2Activates[rank].size() >= 2)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last2Activates[rank].front() + memSpec->tTAW);
|
||||
std::max(earliestTimeToStart, last2Activates[rank].front() + memSpec.tTAW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -273,13 +270,13 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -299,43 +296,43 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRP);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
@@ -357,13 +354,13 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
@@ -381,66 +378,66 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tBURST + memSpec->tRP));
|
||||
earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tBURST + memSpec.tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRP));
|
||||
earliestTimeToStart, lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec.tRP));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFC);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFC);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKESR);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerWideIO", "Unknown command!");
|
||||
|
||||
// Check if command bus is free
|
||||
if (lastCommandOnBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec.tCK);
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#ifndef CHECKERWIDEIO_H
|
||||
#define CHECKERWIDEIO_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecWideIO.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
|
||||
@@ -48,14 +47,14 @@ namespace DRAMSys
|
||||
class CheckerWideIO final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
explicit CheckerWideIO(const Configuration& config);
|
||||
explicit CheckerWideIO(const MemSpecWideIO& memSpec);
|
||||
[[nodiscard]] 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;
|
||||
|
||||
private:
|
||||
const MemSpecWideIO* memSpec;
|
||||
const MemSpecWideIO& memSpec;
|
||||
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
|
||||
@@ -44,32 +44,29 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
CheckerWideIO2::CheckerWideIO2(const Configuration& config) :
|
||||
memSpec(dynamic_cast<const MemSpecWideIO2*>(config.memSpec.get()))
|
||||
CheckerWideIO2::CheckerWideIO2(const MemSpecWideIO2& memSpec) :
|
||||
memSpec(memSpec)
|
||||
{
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("CheckerWideIO2", "Wrong MemSpec chosen");
|
||||
|
||||
lastScheduledByCommandAndBank = std::vector<ControllerVector<Bank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Bank, sc_time>(memSpec->banksPerChannel, scMaxTime));
|
||||
ControllerVector<Bank, sc_time>(memSpec.banksPerChannel, scMaxTime));
|
||||
lastScheduledByCommandAndRank = std::vector<ControllerVector<Rank, sc_time>>(
|
||||
Command::numberOfCommands(),
|
||||
ControllerVector<Rank, sc_time>(memSpec->ranksPerChannel, scMaxTime));
|
||||
ControllerVector<Rank, sc_time>(memSpec.ranksPerChannel, scMaxTime));
|
||||
lastScheduledByCommand = std::vector<sc_time>(Command::numberOfCommands(), scMaxTime);
|
||||
lastCommandOnBus = scMaxTime;
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec->ranksPerChannel);
|
||||
last4Activates = ControllerVector<Rank, std::queue<sc_time>>(memSpec.ranksPerChannel);
|
||||
|
||||
tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK;
|
||||
tRDPRE = tBURST + std::max(2 * memSpec->tCK, memSpec->tRTP) - 2 * memSpec->tCK;
|
||||
tRDPDEN = memSpec->tRL + memSpec->tDQSCK + tBURST + memSpec->tCK;
|
||||
tRDWR = memSpec->tRL + memSpec->tDQSCK + tBURST + memSpec->tCK - memSpec->tWL;
|
||||
tRDWR_R = memSpec->tRL + memSpec->tDQSCK + tBURST + memSpec->tRTRS - memSpec->tWL;
|
||||
tWRPRE = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tWR;
|
||||
tWRPDEN = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tWR;
|
||||
tWRAPDEN = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tWR + memSpec->tCK;
|
||||
tWRRD = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tWTR;
|
||||
tWRRD_R = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tRTRS - memSpec->tRL;
|
||||
tBURST = memSpec.defaultBurstLength / memSpec.dataRate * memSpec.tCK;
|
||||
tRDPRE = tBURST + std::max(2 * memSpec.tCK, memSpec.tRTP) - 2 * memSpec.tCK;
|
||||
tRDPDEN = memSpec.tRL + memSpec.tDQSCK + tBURST + memSpec.tCK;
|
||||
tRDWR = memSpec.tRL + memSpec.tDQSCK + tBURST + memSpec.tCK - memSpec.tWL;
|
||||
tRDWR_R = memSpec.tRL + memSpec.tDQSCK + tBURST + memSpec.tRTRS - memSpec.tWL;
|
||||
tWRPRE = memSpec.tWL + memSpec.tCK + tBURST + memSpec.tWR;
|
||||
tWRPDEN = memSpec.tWL + memSpec.tCK + tBURST + memSpec.tWR;
|
||||
tWRAPDEN = memSpec.tWL + memSpec.tCK + tBURST + memSpec.tWR + memSpec.tCK;
|
||||
tWRRD = memSpec.tWL + memSpec.tCK + tBURST + memSpec.tWTR;
|
||||
tWRRD_R = memSpec.tWL + memSpec.tCK + tBURST + memSpec.tRTRS - memSpec.tRL;
|
||||
}
|
||||
|
||||
sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command,
|
||||
@@ -85,15 +82,15 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command,
|
||||
{
|
||||
unsigned burstLength = ControllerExtension::getBurstLength(payload);
|
||||
assert((burstLength == 4) || (burstLength == 8)); // TODO: BL4/8 OTF
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
assert(burstLength <= memSpec.maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::RD] != lastScheduledByCommandAndRank[Command::RD][rank]
|
||||
@@ -101,11 +98,11 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::RDA] !=
|
||||
lastScheduledByCommandAndRank[Command::RDA][rank]
|
||||
@@ -113,7 +110,7 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
if (command == Command::RDA)
|
||||
{
|
||||
@@ -147,18 +144,18 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
|
||||
command == Command::MWRA)
|
||||
{
|
||||
unsigned burstLength = ControllerExtension::getBurstLength(payload);
|
||||
assert((burstLength == 4) || (burstLength == 8));
|
||||
assert(burstLength <= memSpec->maxBurstLength);
|
||||
assert(burstLength <= memSpec.maxBurstLength);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -184,7 +181,7 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WR][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD);
|
||||
|
||||
lastCommandStart =
|
||||
lastScheduledByCommand[Command::WR] != lastScheduledByCommandAndRank[Command::WR][rank]
|
||||
@@ -192,11 +189,11 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCCD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCCD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommand[Command::WRA] !=
|
||||
lastScheduledByCommandAndRank[Command::WRA][rank]
|
||||
@@ -204,73 +201,73 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command,
|
||||
: scMaxTime;
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec->tRTRS);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tBURST + memSpec.tRTRS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::ACT)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::REFPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW);
|
||||
}
|
||||
else if (command == Command::PREPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RD][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -283,17 +280,17 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + 2 * memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
}
|
||||
else if (command == Command::PREAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRAS);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRAS);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RD][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
@@ -314,107 +311,107 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command,
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + 2 * memSpec->tCK);
|
||||
std::max(earliestTimeToStart, lastCommandStart + 2 * memSpec.tCK);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
}
|
||||
else if (command == Command::REFAB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
}
|
||||
else if (command == Command::REFPB)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRRD);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRRD);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::RDA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec->tRPpb);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tRDPRE + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::WRA][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec->tRPpb);
|
||||
std::max(earliestTimeToStart, lastCommandStart + tWRPRE + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndBank[Command::PREPB][bank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
|
||||
if (last4Activates[rank].size() >= 4)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec->tFAW);
|
||||
std::max(earliestTimeToStart, last4Activates[rank].front() + memSpec.tFAW);
|
||||
}
|
||||
else if (command == Command::PDEA)
|
||||
{
|
||||
@@ -436,13 +433,13 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::PDXA)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::PDEP)
|
||||
{
|
||||
@@ -460,71 +457,71 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command,
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
}
|
||||
else if (command == Command::PDXP)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDEP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKE);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKE);
|
||||
}
|
||||
else if (command == Command::SREFEN)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::ACT][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::RDA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(
|
||||
earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tRDPRE + memSpec->tRPpb));
|
||||
earliestTimeToStart, lastCommandStart + std::max(tRDPDEN, tRDPRE + memSpec.tRPpb));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::WRA][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart =
|
||||
std::max(earliestTimeToStart,
|
||||
lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec->tRPpb));
|
||||
lastCommandStart + std::max(tWRAPDEN, tWRPRE + memSpec.tRPpb));
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PREAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRPab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRPab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::PDXP][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXP);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXP);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFAB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCab);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCab);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::REFPB][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRFCpb);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tRFCpb);
|
||||
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEX][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tXSR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tXSR);
|
||||
}
|
||||
else if (command == Command::SREFEX)
|
||||
{
|
||||
lastCommandStart = lastScheduledByCommandAndRank[Command::SREFEN][rank];
|
||||
if (lastCommandStart != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tCKESR);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec.tCKESR);
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("CheckerWideIO2", "Unknown command!");
|
||||
|
||||
// Check if command bus is free
|
||||
if (lastCommandOnBus != scMaxTime)
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec->tCK);
|
||||
earliestTimeToStart = std::max(earliestTimeToStart, lastCommandOnBus + memSpec.tCK);
|
||||
|
||||
return earliestTimeToStart;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#ifndef CHECKERWIDEIO2_H
|
||||
#define CHECKERWIDEIO2_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecWideIO2.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
|
||||
@@ -48,14 +47,14 @@ namespace DRAMSys
|
||||
class CheckerWideIO2 final : public CheckerIF
|
||||
{
|
||||
public:
|
||||
explicit CheckerWideIO2(const Configuration& config);
|
||||
explicit CheckerWideIO2(const MemSpecWideIO2& memSpec);
|
||||
[[nodiscard]] 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;
|
||||
|
||||
private:
|
||||
const MemSpecWideIO2* memSpec;
|
||||
const MemSpecWideIO2& memSpec;
|
||||
|
||||
std::vector<ControllerVector<Bank, sc_core::sc_time>> lastScheduledByCommandAndBank;
|
||||
std::vector<ControllerVector<Rank, sc_core::sc_time>> lastScheduledByCommandAndRank;
|
||||
|
||||
@@ -41,7 +41,7 @@ using namespace sc_core;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
CmdMuxOldest::CmdMuxOldest(const Configuration& config) : memSpec(*config.memSpec)
|
||||
CmdMuxOldest::CmdMuxOldest(const MemSpec& memSpec) : memSpec(memSpec)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands& readyCommand
|
||||
return {Command::NOP, nullptr, scMaxTime};
|
||||
}
|
||||
|
||||
CmdMuxOldestRasCas::CmdMuxOldestRasCas(const Configuration& config) : memSpec(*config.memSpec)
|
||||
CmdMuxOldestRasCas::CmdMuxOldestRasCas(const MemSpec& memSpec) : memSpec(memSpec)
|
||||
{
|
||||
readyRasCommands.reserve(memSpec.banksPerChannel);
|
||||
readyCasCommands.reserve(memSpec.banksPerChannel);
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#ifndef CMDMUXOLDEST_H
|
||||
#define CMDMUXOLDEST_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpec.h"
|
||||
#include "DRAMSys/controller/cmdmux/CmdMuxIF.h"
|
||||
|
||||
namespace DRAMSys
|
||||
@@ -44,7 +44,7 @@ namespace DRAMSys
|
||||
class CmdMuxOldest : public CmdMuxIF
|
||||
{
|
||||
public:
|
||||
explicit CmdMuxOldest(const Configuration& config);
|
||||
explicit CmdMuxOldest(const MemSpec& memSpec);
|
||||
CommandTuple::Type selectCommand(const ReadyCommands& readyCommands) override;
|
||||
|
||||
private:
|
||||
@@ -55,7 +55,7 @@ private:
|
||||
class CmdMuxOldestRasCas : public CmdMuxIF
|
||||
{
|
||||
public:
|
||||
explicit CmdMuxOldestRasCas(const Configuration& config);
|
||||
explicit CmdMuxOldestRasCas(const MemSpec& memSpec);
|
||||
CommandTuple::Type selectCommand(const ReadyCommands& readyCommands) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -41,7 +41,7 @@ using namespace sc_core;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
CmdMuxStrict::CmdMuxStrict(const Configuration& config) : memSpec(*config.memSpec)
|
||||
CmdMuxStrict::CmdMuxStrict(const MemSpec& memSpec) : memSpec(memSpec)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands& readyCommand
|
||||
return {Command::NOP, nullptr, scMaxTime};
|
||||
}
|
||||
|
||||
CmdMuxStrictRasCas::CmdMuxStrictRasCas(const Configuration& config) : memSpec(*config.memSpec)
|
||||
CmdMuxStrictRasCas::CmdMuxStrictRasCas(const MemSpec& memSpec) : memSpec(memSpec)
|
||||
{
|
||||
readyRasCommands.reserve(memSpec.banksPerChannel);
|
||||
readyCasCommands.reserve(memSpec.banksPerChannel);
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#ifndef CMDMUXSTRICT_H
|
||||
#define CMDMUXSTRICT_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpec.h"
|
||||
#include "DRAMSys/controller/cmdmux/CmdMuxIF.h"
|
||||
|
||||
namespace DRAMSys
|
||||
@@ -44,7 +44,7 @@ namespace DRAMSys
|
||||
class CmdMuxStrict : public CmdMuxIF
|
||||
{
|
||||
public:
|
||||
explicit CmdMuxStrict(const Configuration& config);
|
||||
explicit CmdMuxStrict(const MemSpec& memSpec);
|
||||
CommandTuple::Type selectCommand(const ReadyCommands& readyCommands) override;
|
||||
|
||||
private:
|
||||
@@ -56,7 +56,7 @@ private:
|
||||
class CmdMuxStrictRasCas : public CmdMuxIF
|
||||
{
|
||||
public:
|
||||
explicit CmdMuxStrictRasCas(const Configuration& config);
|
||||
explicit CmdMuxStrictRasCas(const MemSpec& memSpec);
|
||||
CommandTuple::Type selectCommand(const ReadyCommands& readyCommands) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -45,11 +45,12 @@ namespace DRAMSys
|
||||
{
|
||||
|
||||
RefreshManagerAllBank::RefreshManagerAllBank(
|
||||
const Configuration& config,
|
||||
const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager,
|
||||
Rank rank) :
|
||||
memSpec(*config.memSpec),
|
||||
memSpec(memSpec),
|
||||
bankMachinesOnRank(bankMachinesOnRank),
|
||||
powerDownManager(powerDownManager),
|
||||
maxPostponed(static_cast<int>(config.refreshMaxPostponed)),
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
#ifndef REFRESHMANAGERALLBANK_H
|
||||
#define REFRESHMANAGERALLBANK_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpec.h"
|
||||
#include "DRAMSys/controller/McConfig.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
|
||||
|
||||
@@ -53,7 +53,8 @@ class PowerDownManagerIF;
|
||||
class RefreshManagerAllBank final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerAllBank(const Configuration& config,
|
||||
RefreshManagerAllBank(const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager,
|
||||
Rank rank);
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#ifndef REFRESHMANAGERIF_H
|
||||
#define REFRESHMANAGERIF_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/common/dramExtensions.h"
|
||||
#include "DRAMSys/controller/Command.h"
|
||||
#include "DRAMSys/controller/ManagerIF.h"
|
||||
|
||||
|
||||
@@ -44,11 +44,12 @@ namespace DRAMSys
|
||||
{
|
||||
|
||||
RefreshManagerPer2Bank::RefreshManagerPer2Bank(
|
||||
const Configuration& config,
|
||||
const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager,
|
||||
Rank rank) :
|
||||
memSpec(*config.memSpec),
|
||||
memSpec(memSpec),
|
||||
powerDownManager(powerDownManager),
|
||||
maxPostponed(static_cast<int>(config.refreshMaxPostponed * memSpec.banksPerRank / 2)),
|
||||
maxPulledin(-static_cast<int>(config.refreshMaxPulledin * memSpec.banksPerRank / 2))
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
#ifndef REFRESHMANAGERPER2BANK_H
|
||||
#define REFRESHMANAGERPER2BANK_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpec.h"
|
||||
#include "DRAMSys/controller/McConfig.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
|
||||
|
||||
@@ -55,7 +55,8 @@ class PowerDownManagerIF;
|
||||
class RefreshManagerPer2Bank final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerPer2Bank(const Configuration& config,
|
||||
RefreshManagerPer2Bank(const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager,
|
||||
Rank rank);
|
||||
|
||||
@@ -44,11 +44,12 @@ namespace DRAMSys
|
||||
{
|
||||
|
||||
RefreshManagerPerBank::RefreshManagerPerBank(
|
||||
const Configuration& config,
|
||||
const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager,
|
||||
Rank rank) :
|
||||
memSpec(*config.memSpec),
|
||||
memSpec(memSpec),
|
||||
powerDownManager(powerDownManager),
|
||||
maxPostponed(static_cast<int>(config.refreshMaxPostponed * memSpec.banksPerRank)),
|
||||
maxPulledin(-static_cast<int>(config.refreshMaxPulledin * memSpec.banksPerRank))
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
#ifndef REFRESHMANAGERPERBANK_H
|
||||
#define REFRESHMANAGERPERBANK_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpec.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
#include "DRAMSys/controller/McConfig.h"
|
||||
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
|
||||
|
||||
#include <list>
|
||||
@@ -55,7 +55,8 @@ class PowerDownManagerIF;
|
||||
class RefreshManagerPerBank final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerPerBank(const Configuration& config,
|
||||
RefreshManagerPerBank(const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager,
|
||||
Rank rank);
|
||||
|
||||
@@ -44,11 +44,12 @@ namespace DRAMSys
|
||||
{
|
||||
|
||||
RefreshManagerSameBank::RefreshManagerSameBank(
|
||||
const Configuration& config,
|
||||
const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager,
|
||||
Rank rank) :
|
||||
memSpec(*config.memSpec),
|
||||
memSpec(memSpec),
|
||||
powerDownManager(powerDownManager),
|
||||
maxPostponed(static_cast<int>(config.refreshMaxPostponed * memSpec.banksPerGroup)),
|
||||
maxPulledin(-static_cast<int>(config.refreshMaxPulledin * memSpec.banksPerGroup)),
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
#ifndef REFRESHMANAGERSAMEBANK_H
|
||||
#define REFRESHMANAGERSAMEBANK_H
|
||||
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpec.h"
|
||||
#include "DRAMSys/controller/McConfig.h"
|
||||
#include "DRAMSys/controller/checker/CheckerIF.h"
|
||||
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
|
||||
|
||||
@@ -54,7 +54,8 @@ class PowerDownManagerIF;
|
||||
class RefreshManagerSameBank final : public RefreshManagerIF
|
||||
{
|
||||
public:
|
||||
RefreshManagerSameBank(const Configuration& config,
|
||||
RefreshManagerSameBank(const McConfig& config,
|
||||
const MemSpec& memSpec,
|
||||
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
|
||||
PowerDownManagerIF& powerDownManager,
|
||||
Rank rank);
|
||||
|
||||
@@ -43,17 +43,17 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
SchedulerFifo::SchedulerFifo(const Configuration& config)
|
||||
SchedulerFifo::SchedulerFifo(const McConfig& config, const MemSpec& memSpec)
|
||||
{
|
||||
buffer =
|
||||
ControllerVector<Bank, std::deque<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
buffer = ControllerVector<Bank, std::deque<tlm_generic_payload*>>(memSpec.banksPerChannel);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
if (config.schedulerBuffer == Config::SchedulerBufferType::Bankwise)
|
||||
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize,
|
||||
config.memSpec->banksPerChannel);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
|
||||
bufferCounter = std::make_unique<BufferCounterReadWrite>(config.requestBufferSizeRead, config.requestBufferSizeWrite);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
|
||||
memSpec.banksPerChannel);
|
||||
else if (config.schedulerBuffer == Config::SchedulerBufferType::ReadWrite)
|
||||
bufferCounter = std::make_unique<BufferCounterReadWrite>(config.requestBufferSizeRead,
|
||||
config.requestBufferSizeWrite);
|
||||
else if (config.schedulerBuffer == Config::SchedulerBufferType::Shared)
|
||||
bufferCounter = std::make_unique<BufferCounterShared>(config.requestBufferSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "DRAMSys/controller/BankMachine.h"
|
||||
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
|
||||
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
|
||||
#include "DRAMSys/controller/McConfig.h"
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
@@ -51,7 +52,7 @@ namespace DRAMSys
|
||||
class SchedulerFifo final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
explicit SchedulerFifo(const Configuration& config);
|
||||
explicit SchedulerFifo(const McConfig& config, const MemSpec& memSpec);
|
||||
[[nodiscard]] bool hasBufferSpace() const override;
|
||||
void storeRequest(tlm::tlm_generic_payload& payload) override;
|
||||
void removeRequest(tlm::tlm_generic_payload& payload) override;
|
||||
|
||||
@@ -43,17 +43,17 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
SchedulerFrFcfs::SchedulerFrFcfs(const Configuration& config)
|
||||
SchedulerFrFcfs::SchedulerFrFcfs(const McConfig& config, const MemSpec& memSpec)
|
||||
{
|
||||
buffer =
|
||||
ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
buffer = ControllerVector<Bank, std::list<tlm_generic_payload*>>(memSpec.banksPerChannel);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
if (config.schedulerBuffer == Config::SchedulerBufferType::Bankwise)
|
||||
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize,
|
||||
config.memSpec->banksPerChannel);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
|
||||
bufferCounter = std::make_unique<BufferCounterReadWrite>(config.requestBufferSizeRead, config.requestBufferSizeWrite);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
|
||||
memSpec.banksPerChannel);
|
||||
else if (config.schedulerBuffer == Config::SchedulerBufferType::ReadWrite)
|
||||
bufferCounter = std::make_unique<BufferCounterReadWrite>(config.requestBufferSizeRead,
|
||||
config.requestBufferSizeWrite);
|
||||
else if (config.schedulerBuffer == Config::SchedulerBufferType::Shared)
|
||||
bufferCounter = std::make_unique<BufferCounterShared>(config.requestBufferSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "DRAMSys/common/dramExtensions.h"
|
||||
#include "DRAMSys/controller/BankMachine.h"
|
||||
#include "DRAMSys/controller/McConfig.h"
|
||||
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
|
||||
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
|
||||
|
||||
@@ -51,7 +52,7 @@ namespace DRAMSys
|
||||
class SchedulerFrFcfs final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
explicit SchedulerFrFcfs(const Configuration& config);
|
||||
explicit SchedulerFrFcfs(const McConfig& config, const MemSpec& memSpec);
|
||||
[[nodiscard]] bool hasBufferSpace() const override;
|
||||
void storeRequest(tlm::tlm_generic_payload& payload) override;
|
||||
void removeRequest(tlm::tlm_generic_payload& payload) override;
|
||||
|
||||
@@ -43,18 +43,17 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
SchedulerFrFcfsGrp::SchedulerFrFcfsGrp(const Configuration& config)
|
||||
SchedulerFrFcfsGrp::SchedulerFrFcfsGrp(const McConfig& config, const MemSpec& memSpec)
|
||||
{
|
||||
buffer =
|
||||
ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
buffer = ControllerVector<Bank, std::list<tlm_generic_payload*>>(memSpec.banksPerChannel);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
if (config.schedulerBuffer == Config::SchedulerBufferType::Bankwise)
|
||||
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize,
|
||||
config.memSpec->banksPerChannel);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
|
||||
memSpec.banksPerChannel);
|
||||
else if (config.schedulerBuffer == Config::SchedulerBufferType::ReadWrite)
|
||||
bufferCounter = std::make_unique<BufferCounterReadWrite>(config.requestBufferSizeRead,
|
||||
config.requestBufferSizeWrite);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
|
||||
else if (config.schedulerBuffer == Config::SchedulerBufferType::Shared)
|
||||
bufferCounter = std::make_unique<BufferCounterShared>(config.requestBufferSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace DRAMSys
|
||||
class SchedulerFrFcfsGrp final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
explicit SchedulerFrFcfsGrp(const Configuration& config);
|
||||
explicit SchedulerFrFcfsGrp(const McConfig& config, const MemSpec& memSpec);
|
||||
[[nodiscard]] bool hasBufferSpace() const override;
|
||||
void storeRequest(tlm::tlm_generic_payload& payload) override;
|
||||
void removeRequest(tlm::tlm_generic_payload& payload) override;
|
||||
|
||||
@@ -43,20 +43,18 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
SchedulerGrpFrFcfs::SchedulerGrpFrFcfs(const Configuration& config)
|
||||
SchedulerGrpFrFcfs::SchedulerGrpFrFcfs(const McConfig& config, const MemSpec& memSpec)
|
||||
{
|
||||
readBuffer =
|
||||
ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
writeBuffer =
|
||||
ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
readBuffer = ControllerVector<Bank, std::list<tlm_generic_payload*>>(memSpec.banksPerChannel);
|
||||
writeBuffer = ControllerVector<Bank, std::list<tlm_generic_payload*>>(memSpec.banksPerChannel);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
if (config.schedulerBuffer == Config::SchedulerBufferType::Bankwise)
|
||||
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize,
|
||||
config.memSpec->banksPerChannel);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
|
||||
memSpec.banksPerChannel);
|
||||
else if (config.schedulerBuffer == Config::SchedulerBufferType::ReadWrite)
|
||||
bufferCounter = std::make_unique<BufferCounterReadWrite>(config.requestBufferSizeRead,
|
||||
config.requestBufferSizeWrite);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
|
||||
else if (config.schedulerBuffer == Config::SchedulerBufferType::Shared)
|
||||
bufferCounter = std::make_unique<BufferCounterShared>(config.requestBufferSize);
|
||||
|
||||
SC_REPORT_WARNING("SchedulerGrpFrFcfs", "Hazard detection not yet implemented!");
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace DRAMSys
|
||||
class SchedulerGrpFrFcfs final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
explicit SchedulerGrpFrFcfs(const Configuration& config);
|
||||
explicit SchedulerGrpFrFcfs(const McConfig& config, const MemSpec& memSpec);
|
||||
[[nodiscard]] bool hasBufferSpace() const override;
|
||||
void storeRequest(tlm::tlm_generic_payload& payload) override;
|
||||
void removeRequest(tlm::tlm_generic_payload& payload) override;
|
||||
|
||||
@@ -43,22 +43,22 @@ using namespace tlm;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
SchedulerGrpFrFcfsWm::SchedulerGrpFrFcfsWm(const Configuration& config) :
|
||||
SchedulerGrpFrFcfsWm::SchedulerGrpFrFcfsWm(const McConfig& config, const MemSpec& memSpec) :
|
||||
lowWatermark(config.lowWatermark),
|
||||
highWatermark(config.highWatermark)
|
||||
{
|
||||
readBuffer =
|
||||
ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
ControllerVector<Bank, std::list<tlm_generic_payload*>>(memSpec.banksPerChannel);
|
||||
writeBuffer =
|
||||
ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
|
||||
ControllerVector<Bank, std::list<tlm_generic_payload*>>(memSpec.banksPerChannel);
|
||||
|
||||
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
|
||||
if (config.schedulerBuffer == Config::SchedulerBufferType::Bankwise)
|
||||
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize,
|
||||
config.memSpec->banksPerChannel);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
|
||||
memSpec.banksPerChannel);
|
||||
else if (config.schedulerBuffer == Config::SchedulerBufferType::ReadWrite)
|
||||
bufferCounter = std::make_unique<BufferCounterReadWrite>(config.requestBufferSizeRead,
|
||||
config.requestBufferSizeWrite);
|
||||
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
|
||||
else if (config.schedulerBuffer == Config::SchedulerBufferType::Shared)
|
||||
bufferCounter = std::make_unique<BufferCounterShared>(config.requestBufferSize);
|
||||
|
||||
if (lowWatermark == 0 || lowWatermark >= highWatermark)
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#define SCHEDULERGRPFRFCFSWM_H
|
||||
|
||||
#include "DRAMSys/common/dramExtensions.h"
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/controller/BankMachine.h"
|
||||
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
|
||||
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
|
||||
@@ -52,7 +51,7 @@ namespace DRAMSys
|
||||
class SchedulerGrpFrFcfsWm final : public SchedulerIF
|
||||
{
|
||||
public:
|
||||
explicit SchedulerGrpFrFcfsWm(const Configuration& config);
|
||||
explicit SchedulerGrpFrFcfsWm(const McConfig& config, const MemSpec& memSpec);
|
||||
[[nodiscard]] bool hasBufferSpace() const override;
|
||||
void storeRequest(tlm::tlm_generic_payload& payload) override;
|
||||
void removeRequest(tlm::tlm_generic_payload& payload) override;
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
*/
|
||||
|
||||
#include "AddressDecoder.h"
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <cmath>
|
||||
@@ -71,7 +70,8 @@ static void addMapping(std::vector<Config::AddressMapping::BitEntry> const& mapp
|
||||
}
|
||||
}
|
||||
|
||||
AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping& addressMapping)
|
||||
AddressDecoder::AddressDecoder(const Config::AddressMapping& addressMapping,
|
||||
const MemSpec& memSpec)
|
||||
{
|
||||
if (const auto& channelBits = addressMapping.CHANNEL_BIT)
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#define ADDRESSDECODER_H
|
||||
|
||||
#include "DRAMSys/config/DRAMSysConfiguration.h"
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpec.h"
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -81,7 +81,7 @@ struct DecodedAddress
|
||||
class AddressDecoder
|
||||
{
|
||||
public:
|
||||
AddressDecoder(const DRAMSys::Config::AddressMapping& addressMapping);
|
||||
AddressDecoder(const Config::AddressMapping& addressMapping, const MemSpec& memSpec);
|
||||
|
||||
[[nodiscard]] DecodedAddress decodeAddress(uint64_t encAddr) const;
|
||||
[[nodiscard]] unsigned decodeChannel(uint64_t encAddr) const;
|
||||
|
||||
@@ -40,10 +40,8 @@
|
||||
#include "Arbiter.h"
|
||||
|
||||
#include "DRAMSys/common/DebugManager.h"
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/simulation/AddressDecoder.h"
|
||||
|
||||
#include "DRAMSys/config/DRAMSysConfiguration.h"
|
||||
#include "DRAMSys/simulation/AddressDecoder.h"
|
||||
|
||||
using namespace sc_core;
|
||||
using namespace tlm;
|
||||
@@ -52,16 +50,18 @@ namespace DRAMSys
|
||||
{
|
||||
|
||||
Arbiter::Arbiter(const sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const SimConfig& simConfig,
|
||||
const McConfig& mcConfig,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder) :
|
||||
sc_module(name),
|
||||
addressDecoder(addressDecoder),
|
||||
payloadEventQueue(this, &Arbiter::peqCallback),
|
||||
tCK(config.memSpec->tCK),
|
||||
arbitrationDelayFw(config.arbitrationDelayFw),
|
||||
arbitrationDelayBw(config.arbitrationDelayBw),
|
||||
bytesPerBeat(config.memSpec->dataBusWidth / 8),
|
||||
addressOffset(config.addressOffset)
|
||||
tCK(memSpec.tCK),
|
||||
arbitrationDelayFw(mcConfig.arbitrationDelayFw),
|
||||
arbitrationDelayBw(mcConfig.arbitrationDelayBw),
|
||||
bytesPerBeat(memSpec.dataBusWidth / 8),
|
||||
addressOffset(simConfig.addressOffset)
|
||||
{
|
||||
iSocket.register_nb_transport_bw(this, &Arbiter::nb_transport_bw);
|
||||
tSocket.register_nb_transport_fw(this, &Arbiter::nb_transport_fw);
|
||||
@@ -70,25 +70,31 @@ Arbiter::Arbiter(const sc_module_name& name,
|
||||
}
|
||||
|
||||
ArbiterSimple::ArbiterSimple(const sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const SimConfig& simConfig,
|
||||
const McConfig& mcConfig,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder) :
|
||||
Arbiter(name, config, addressDecoder)
|
||||
Arbiter(name, simConfig, mcConfig, memSpec, addressDecoder)
|
||||
{
|
||||
}
|
||||
|
||||
ArbiterFifo::ArbiterFifo(const sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const SimConfig& simConfig,
|
||||
const McConfig& mcConfig,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder) :
|
||||
Arbiter(name, config, addressDecoder),
|
||||
maxActiveTransactionsPerThread(config.maxActiveTransactions)
|
||||
Arbiter(name, simConfig, mcConfig, memSpec, addressDecoder),
|
||||
maxActiveTransactionsPerThread(mcConfig.maxActiveTransactions)
|
||||
{
|
||||
}
|
||||
|
||||
ArbiterReorder::ArbiterReorder(const sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const SimConfig& simConfig,
|
||||
const McConfig& mcConfig,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder) :
|
||||
Arbiter(name, config, addressDecoder),
|
||||
maxActiveTransactions(config.maxActiveTransactions)
|
||||
Arbiter(name, simConfig, mcConfig, memSpec, addressDecoder),
|
||||
maxActiveTransactions(mcConfig.maxActiveTransactions)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@
|
||||
#define ARBITER_H
|
||||
|
||||
#include "DRAMSys/common/dramExtensions.h"
|
||||
#include "DRAMSys/controller/McConfig.h"
|
||||
#include "DRAMSys/simulation/AddressDecoder.h"
|
||||
#include "DRAMSys/simulation/SimConfig.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
@@ -67,7 +69,9 @@ public:
|
||||
|
||||
protected:
|
||||
Arbiter(const sc_core::sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const SimConfig& simConfig,
|
||||
const McConfig& mcConfig,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder);
|
||||
SC_HAS_PROCESS(Arbiter);
|
||||
|
||||
@@ -109,7 +113,9 @@ class ArbiterSimple final : public Arbiter
|
||||
{
|
||||
public:
|
||||
ArbiterSimple(const sc_core::sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const SimConfig& simConfig,
|
||||
const McConfig& mcConfig,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder);
|
||||
SC_HAS_PROCESS(ArbiterSimple);
|
||||
|
||||
@@ -124,7 +130,9 @@ class ArbiterFifo final : public Arbiter
|
||||
{
|
||||
public:
|
||||
ArbiterFifo(const sc_core::sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const SimConfig& simConfig,
|
||||
const McConfig& mcConfig,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder);
|
||||
SC_HAS_PROCESS(ArbiterFifo);
|
||||
|
||||
@@ -146,7 +154,9 @@ class ArbiterReorder final : public Arbiter
|
||||
{
|
||||
public:
|
||||
ArbiterReorder(const sc_core::sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const SimConfig& simConfig,
|
||||
const McConfig& mcConfig,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder);
|
||||
SC_HAS_PROCESS(ArbiterReorder);
|
||||
|
||||
|
||||
@@ -42,8 +42,31 @@
|
||||
|
||||
#include "DRAMSys/common/DebugManager.h"
|
||||
#include "DRAMSys/common/utils.h"
|
||||
#include "DRAMSys/config/McConfig.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpec.h"
|
||||
#include "DRAMSys/controller/Controller.h"
|
||||
|
||||
#include "DRAMSys/configuration/memspec/MemSpecDDR3.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecDDR4.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecGDDR5.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecGDDR5X.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecGDDR6.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecHBM2.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecLPDDR4.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecSTTMRAM.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecWideIO.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpecWideIO2.h"
|
||||
|
||||
#ifdef DDR5_SIM
|
||||
#include "DRAMSys/configuration/memspec/MemSpecDDR5.h"
|
||||
#endif
|
||||
#ifdef LPDDR5_SIM
|
||||
#include "DRAMSys/configuration/memspec/MemSpecLPDDR5.h"
|
||||
#endif
|
||||
#ifdef HBM3_SIM
|
||||
#include "DRAMSys/configuration/memspec/MemSpecHBM3.h"
|
||||
#endif
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
@@ -53,36 +76,48 @@
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
DRAMSys::DRAMSys(const sc_core::sc_module_name& name,
|
||||
const ::DRAMSys::Config::Configuration& configLib) :
|
||||
DRAMSys(name, configLib, true)
|
||||
DRAMSys::DRAMSys(const sc_core::sc_module_name& name, const Config::Configuration& config) :
|
||||
DRAMSys(name, config, true)
|
||||
{
|
||||
}
|
||||
|
||||
DRAMSys::DRAMSys(const sc_core::sc_module_name& name,
|
||||
const ::DRAMSys::Config::Configuration& configLib,
|
||||
const Config::Configuration& config,
|
||||
bool initAndBind) :
|
||||
sc_module(name),
|
||||
tSocket("DRAMSys_tSocket")
|
||||
memSpec(createMemSpec(config.memspec)),
|
||||
simConfig(config.simconfig),
|
||||
mcConfig(config.mcconfig, *memSpec),
|
||||
addressDecoder(std::make_unique<AddressDecoder>(config.addressmapping, *memSpec)),
|
||||
arbiter(createArbiter(simConfig, mcConfig, *memSpec, *addressDecoder))
|
||||
{
|
||||
logo();
|
||||
|
||||
// Load configLib and initialize modules
|
||||
// Important: The memSpec needs to be the first configuration to be loaded!
|
||||
config.loadMemSpec(configLib.memspec);
|
||||
config.loadMCConfig(configLib.mcconfig);
|
||||
config.loadSimConfig(configLib.simconfig);
|
||||
addressDecoder->plausibilityCheck(*memSpec);
|
||||
addressDecoder->print();
|
||||
|
||||
// Setup the debug manager:
|
||||
setupDebugManager(config.simulationName);
|
||||
setupDebugManager(simConfig.simulationName);
|
||||
|
||||
if (initAndBind)
|
||||
{
|
||||
// Instantiate all internal DRAMSys modules:
|
||||
instantiateModules(configLib.addressmapping);
|
||||
for (std::size_t i = 0; i < memSpec->numberOfChannels; i++)
|
||||
{
|
||||
controllers.emplace_back(std::make_unique<Controller>(
|
||||
("controller" + std::to_string(i)).c_str(), mcConfig, *memSpec, *addressDecoder));
|
||||
|
||||
drams.emplace_back(
|
||||
std::make_unique<Dram>(("dram" + std::to_string(i)).c_str(), simConfig, *memSpec));
|
||||
|
||||
if (simConfig.checkTLM2Protocol)
|
||||
controllersTlmCheckers.push_back(
|
||||
std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>(
|
||||
("TlmCheckerController" + std::to_string(i)).c_str()));
|
||||
}
|
||||
|
||||
// Connect all internal DRAMSys modules:
|
||||
bindSockets();
|
||||
report(headline);
|
||||
report();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,14 +136,9 @@ void DRAMSys::registerIdleCallback(const std::function<void()>& idleCallback)
|
||||
}
|
||||
}
|
||||
|
||||
const Configuration& DRAMSys::getConfig() const
|
||||
{
|
||||
return config;
|
||||
}
|
||||
|
||||
void DRAMSys::end_of_simulation()
|
||||
{
|
||||
if (config.powerAnalysis)
|
||||
if (simConfig.powerAnalysis)
|
||||
{
|
||||
for (auto& dram : drams)
|
||||
dram->reportPower();
|
||||
@@ -140,7 +170,7 @@ void DRAMSys::setupDebugManager([[maybe_unused]] const std::string& traceName) c
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
auto& dbg = DebugManager::getInstance();
|
||||
bool debugEnabled = config.debug;
|
||||
bool debugEnabled = simConfig.debug;
|
||||
bool writeToConsole = false;
|
||||
bool writeToFile = true;
|
||||
dbg.setup(debugEnabled, writeToConsole, writeToFile);
|
||||
@@ -149,42 +179,13 @@ void DRAMSys::setupDebugManager([[maybe_unused]] const std::string& traceName) c
|
||||
#endif
|
||||
}
|
||||
|
||||
void DRAMSys::instantiateModules(const ::DRAMSys::Config::AddressMapping& addressMapping)
|
||||
{
|
||||
addressDecoder = std::make_unique<AddressDecoder>(addressMapping);
|
||||
addressDecoder->plausibilityCheck(*config.memSpec);
|
||||
addressDecoder->print();
|
||||
|
||||
// Create arbiter
|
||||
if (config.arbiter == Configuration::Arbiter::Simple)
|
||||
arbiter = std::make_unique<ArbiterSimple>("arbiter", config, *addressDecoder);
|
||||
else if (config.arbiter == Configuration::Arbiter::Fifo)
|
||||
arbiter = std::make_unique<ArbiterFifo>("arbiter", config, *addressDecoder);
|
||||
else if (config.arbiter == Configuration::Arbiter::Reorder)
|
||||
arbiter = std::make_unique<ArbiterReorder>("arbiter", config, *addressDecoder);
|
||||
|
||||
// Create controllers and DRAMs
|
||||
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(), config, *config.memSpec, *addressDecoder));
|
||||
|
||||
drams.emplace_back(std::make_unique<Dram>(("dram" + std::to_string(i)).c_str(), config));
|
||||
|
||||
if (config.checkTLM2Protocol)
|
||||
controllersTlmCheckers.push_back(
|
||||
std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>(
|
||||
("TlmCheckerController" + std::to_string(i)).c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
void DRAMSys::bindSockets()
|
||||
{
|
||||
tSocket.bind(arbiter->tSocket);
|
||||
|
||||
for (unsigned i = 0; i < config.memSpec->numberOfChannels; i++)
|
||||
for (unsigned i = 0; i < memSpec->numberOfChannels; i++)
|
||||
{
|
||||
if (config.checkTLM2Protocol)
|
||||
if (simConfig.checkTLM2Protocol)
|
||||
{
|
||||
arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket);
|
||||
controllersTlmCheckers[i]->initiator_socket.bind(controllers[i]->tSocket);
|
||||
@@ -197,10 +198,84 @@ void DRAMSys::bindSockets()
|
||||
}
|
||||
}
|
||||
|
||||
void DRAMSys::report(std::string_view message)
|
||||
void DRAMSys::report()
|
||||
{
|
||||
PRINTDEBUGMESSAGE(name(), message.data());
|
||||
std::cout << message << std::endl;
|
||||
PRINTDEBUGMESSAGE(name(), headline.data());
|
||||
std::cout << headline << std::endl;
|
||||
}
|
||||
|
||||
std::unique_ptr<const MemSpec> DRAMSys::createMemSpec(const Config::MemSpec& memSpec)
|
||||
{
|
||||
auto memoryType = memSpec.memoryType;
|
||||
|
||||
if (memoryType == Config::MemoryType::DDR3)
|
||||
return std::make_unique<const MemSpecDDR3>(memSpec);
|
||||
|
||||
if (memoryType == Config::MemoryType::DDR4)
|
||||
return std::make_unique<const MemSpecDDR4>(memSpec);
|
||||
|
||||
if (memoryType == Config::MemoryType::LPDDR4)
|
||||
return std::make_unique<const MemSpecLPDDR4>(memSpec);
|
||||
|
||||
if (memoryType == Config::MemoryType::WideIO)
|
||||
return std::make_unique<const MemSpecWideIO>(memSpec);
|
||||
|
||||
if (memoryType == Config::MemoryType::WideIO2)
|
||||
return std::make_unique<const MemSpecWideIO2>(memSpec);
|
||||
|
||||
if (memoryType == Config::MemoryType::HBM2)
|
||||
return std::make_unique<const MemSpecHBM2>(memSpec);
|
||||
|
||||
if (memoryType == Config::MemoryType::GDDR5)
|
||||
return std::make_unique<const MemSpecGDDR5>(memSpec);
|
||||
|
||||
if (memoryType == Config::MemoryType::GDDR5X)
|
||||
return std::make_unique<const MemSpecGDDR5X>(memSpec);
|
||||
|
||||
if (memoryType == Config::MemoryType::GDDR6)
|
||||
return std::make_unique<const MemSpecGDDR6>(memSpec);
|
||||
|
||||
if (memoryType == Config::MemoryType::STTMRAM)
|
||||
return std::make_unique<const MemSpecSTTMRAM>(memSpec);
|
||||
|
||||
#ifdef DDR5_SIM
|
||||
if (memoryType == Config::MemoryType::DDR5)
|
||||
return std::make_unique<const MemSpecDDR5>(memSpec);
|
||||
#endif
|
||||
|
||||
#ifdef LPDDR5_SIM
|
||||
if (memoryType == Config::MemoryType::LPDDR5)
|
||||
return std::make_unique<const MemSpecLPDDR5>(memSpec);
|
||||
#endif
|
||||
|
||||
#ifdef HBM3_SIM
|
||||
if (memoryType == Config::MemoryType::HBM3)
|
||||
return std::make_unique<const MemSpecHBM3>(memSpec);
|
||||
#endif
|
||||
|
||||
SC_REPORT_FATAL("Configuration", "Unsupported DRAM type");
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<Arbiter> DRAMSys::createArbiter(const SimConfig& simConfig,
|
||||
const McConfig& mcConfig,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder)
|
||||
{
|
||||
if (mcConfig.arbiter == Config::ArbiterType::Simple)
|
||||
return std::make_unique<ArbiterSimple>(
|
||||
"arbiter", simConfig, mcConfig, memSpec, addressDecoder);
|
||||
|
||||
if (mcConfig.arbiter == Config::ArbiterType::Fifo)
|
||||
return std::make_unique<ArbiterFifo>(
|
||||
"arbiter", simConfig, mcConfig, memSpec, addressDecoder);
|
||||
|
||||
if (mcConfig.arbiter == Config::ArbiterType::Reorder)
|
||||
return std::make_unique<ArbiterReorder>(
|
||||
"arbiter", simConfig, mcConfig, memSpec, addressDecoder);
|
||||
|
||||
SC_REPORT_FATAL("DRAMSys", "Invalid Arbiter");
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -44,10 +44,12 @@
|
||||
#include "DRAMSys/common/Serialize.h"
|
||||
#include "DRAMSys/common/tlm2_base_protocol_checker.h"
|
||||
#include "DRAMSys/config/DRAMSysConfiguration.h"
|
||||
#include "DRAMSys/config/SimConfig.h"
|
||||
#include "DRAMSys/controller/Controller.h"
|
||||
#include "DRAMSys/simulation/AddressDecoder.h"
|
||||
#include "DRAMSys/simulation/Arbiter.h"
|
||||
#include "DRAMSys/simulation/ReorderBuffer.h"
|
||||
#include "DRAMSys/simulation/SimConfig.h"
|
||||
#include "DRAMSys/simulation/dram/Dram.h"
|
||||
|
||||
#include <list>
|
||||
@@ -64,12 +66,12 @@ namespace DRAMSys
|
||||
class DRAMSys : public sc_core::sc_module
|
||||
{
|
||||
public:
|
||||
tlm_utils::multi_passthrough_target_socket<DRAMSys> tSocket;
|
||||
tlm_utils::multi_passthrough_target_socket<DRAMSys> tSocket{"DRAMSys_tSocket"};
|
||||
|
||||
SC_HAS_PROCESS(DRAMSys);
|
||||
DRAMSys(const sc_core::sc_module_name& name, const ::DRAMSys::Config::Configuration& configLib);
|
||||
DRAMSys(const sc_core::sc_module_name& name, const Config::Configuration& config);
|
||||
|
||||
const Configuration& getConfig() const;
|
||||
const MemSpec& getMemSpec() const { return *memSpec; }
|
||||
const AddressDecoder& getAddressDecoder() const { return *addressDecoder; }
|
||||
|
||||
/**
|
||||
@@ -85,12 +87,16 @@ public:
|
||||
|
||||
protected:
|
||||
DRAMSys(const sc_core::sc_module_name& name,
|
||||
const ::DRAMSys::Config::Configuration& configLib,
|
||||
const Config::Configuration& config,
|
||||
bool initAndBind);
|
||||
|
||||
void end_of_simulation() override;
|
||||
|
||||
Configuration config;
|
||||
std::unique_ptr<const MemSpec> memSpec;
|
||||
SimConfig simConfig;
|
||||
McConfig mcConfig;
|
||||
|
||||
std::unique_ptr<AddressDecoder> addressDecoder;
|
||||
|
||||
// TLM 2.0 Protocol Checkers
|
||||
std::vector<std::unique_ptr<tlm_utils::tlm2_base_protocol_checker<>>> controllersTlmCheckers;
|
||||
@@ -107,15 +113,20 @@ protected:
|
||||
// DRAM units
|
||||
std::vector<std::unique_ptr<Dram>> drams;
|
||||
|
||||
std::unique_ptr<AddressDecoder> addressDecoder;
|
||||
|
||||
void report(std::string_view message);
|
||||
void report();
|
||||
void bindSockets();
|
||||
|
||||
private:
|
||||
static void logo();
|
||||
void instantiateModules(const ::DRAMSys::Config::AddressMapping& addressMapping);
|
||||
static std::unique_ptr<const MemSpec> createMemSpec(const Config::MemSpec& memSpec);
|
||||
static std::unique_ptr<Arbiter> createArbiter(const SimConfig& simConfig,
|
||||
const McConfig& mcConfig,
|
||||
const MemSpec& memSpec,
|
||||
const AddressDecoder& addressDecoder);
|
||||
|
||||
void setupDebugManager(const std::string& traceName) const;
|
||||
|
||||
static constexpr Config::ArbiterType DEFAULT_ARBITER = Config::ArbiterType::Simple;
|
||||
};
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
@@ -46,30 +46,53 @@ namespace DRAMSys
|
||||
{
|
||||
|
||||
DRAMSysRecordable::DRAMSysRecordable(const sc_core::sc_module_name& name,
|
||||
const ::DRAMSys::Config::Configuration& configLib) :
|
||||
DRAMSys(name, configLib, false)
|
||||
const Config::Configuration& config) :
|
||||
DRAMSys(name, config, 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 (!configLib.simulationid.empty())
|
||||
if (!config.simulationid.empty())
|
||||
{
|
||||
std::string sid = configLib.simulationid;
|
||||
traceName = sid + '_' + config.simulationName;
|
||||
std::string sid = config.simulationid;
|
||||
traceName = sid + '_' + simConfig.simulationName;
|
||||
}
|
||||
else
|
||||
traceName = config.simulationName;
|
||||
traceName = simConfig.simulationName;
|
||||
|
||||
// Create and properly initialize TLM recorders.
|
||||
// They need to be ready before creating some modules.
|
||||
setupTlmRecorders(traceName, config);
|
||||
|
||||
// Create controllers and DRAMs
|
||||
for (std::size_t i = 0; i < memSpec->numberOfChannels; i++)
|
||||
{
|
||||
controllers.emplace_back(
|
||||
std::make_unique<ControllerRecordable>(("controller" + std::to_string(i)).c_str(),
|
||||
mcConfig,
|
||||
simConfig,
|
||||
*memSpec,
|
||||
*addressDecoder,
|
||||
tlmRecorders[i]));
|
||||
|
||||
drams.emplace_back(std::make_unique<DramRecordable>(
|
||||
("dram" + std::to_string(i)).c_str(), simConfig, *memSpec, tlmRecorders[i]));
|
||||
|
||||
if (simConfig.checkTLM2Protocol)
|
||||
controllersTlmCheckers.emplace_back(
|
||||
std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>(
|
||||
("TLMCheckerController" + std::to_string(i)).c_str()));
|
||||
}
|
||||
|
||||
instantiateModules(traceName, configLib);
|
||||
bindSockets();
|
||||
report(headline);
|
||||
report();
|
||||
}
|
||||
|
||||
void DRAMSysRecordable::end_of_simulation()
|
||||
{
|
||||
// Report power before TLM recorders are finalized
|
||||
if (config.powerAnalysis)
|
||||
if (simConfig.powerAnalysis)
|
||||
{
|
||||
for (auto& dram : drams)
|
||||
dram->reportPower();
|
||||
@@ -80,14 +103,14 @@ void DRAMSysRecordable::end_of_simulation()
|
||||
}
|
||||
|
||||
void DRAMSysRecordable::setupTlmRecorders(const std::string& traceName,
|
||||
const ::DRAMSys::Config::Configuration& configLib)
|
||||
const Config::Configuration& config)
|
||||
{
|
||||
// Create TLM Recorders, one per channel.
|
||||
// Reserve is required because the recorders use double buffers that are accessed with pointers.
|
||||
// Without a reserve, the vector reallocates storage before inserting a second
|
||||
// element and the pointers are not valid anymore.
|
||||
tlmRecorders.reserve(config.memSpec->numberOfChannels);
|
||||
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
|
||||
tlmRecorders.reserve(memSpec->numberOfChannels);
|
||||
for (std::size_t i = 0; i < memSpec->numberOfChannels; i++)
|
||||
{
|
||||
std::string dbName =
|
||||
std::string(name()) + "_" + traceName + "_ch" + std::to_string(i) + ".tdb";
|
||||
@@ -95,50 +118,16 @@ void DRAMSysRecordable::setupTlmRecorders(const std::string& traceName,
|
||||
|
||||
nlohmann::json mcconfig;
|
||||
nlohmann::json memspec;
|
||||
mcconfig[Config::McConfig::KEY] = configLib.mcconfig;
|
||||
memspec[Config::MemSpec::KEY] = configLib.memspec;
|
||||
mcconfig[Config::McConfig::KEY] = config.mcconfig;
|
||||
memspec[Config::MemSpec::KEY] = config.memspec;
|
||||
|
||||
tlmRecorders.emplace_back(
|
||||
recorderName, config, dbName, mcconfig.dump(), memspec.dump(), config.simulationName);
|
||||
}
|
||||
}
|
||||
|
||||
void DRAMSysRecordable::instantiateModules(const std::string& traceName,
|
||||
const ::DRAMSys::Config::Configuration& configLib)
|
||||
{
|
||||
addressDecoder = std::make_unique<AddressDecoder>(configLib.addressmapping);
|
||||
addressDecoder->plausibilityCheck(*config.memSpec);
|
||||
addressDecoder->print();
|
||||
|
||||
// Create and properly initialize TLM recorders.
|
||||
// They need to be ready before creating some modules.
|
||||
setupTlmRecorders(traceName, configLib);
|
||||
|
||||
// Create arbiter
|
||||
if (config.arbiter == Configuration::Arbiter::Simple)
|
||||
arbiter = std::make_unique<ArbiterSimple>("arbiter", config, *addressDecoder);
|
||||
else if (config.arbiter == Configuration::Arbiter::Fifo)
|
||||
arbiter = std::make_unique<ArbiterFifo>("arbiter", config, *addressDecoder);
|
||||
else if (config.arbiter == Configuration::Arbiter::Reorder)
|
||||
arbiter = std::make_unique<ArbiterReorder>("arbiter", config, *addressDecoder);
|
||||
|
||||
// Create controllers and DRAMs
|
||||
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(),
|
||||
config,
|
||||
*config.memSpec,
|
||||
*addressDecoder,
|
||||
tlmRecorders[i]));
|
||||
|
||||
drams.emplace_back(std::make_unique<DramRecordable>(
|
||||
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
|
||||
|
||||
if (config.checkTLM2Protocol)
|
||||
controllersTlmCheckers.emplace_back(
|
||||
std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>(
|
||||
("TLMCheckerController" + std::to_string(i)).c_str()));
|
||||
tlmRecorders.emplace_back(recorderName,
|
||||
simConfig,
|
||||
mcConfig,*memSpec,
|
||||
dbName,
|
||||
mcconfig.dump(),
|
||||
memspec.dump(),
|
||||
simConfig.simulationName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,9 +38,8 @@
|
||||
#define DRAMSYSRECORDABLE_H
|
||||
|
||||
#include "DRAMSys/common/TlmRecorder.h"
|
||||
#include "DRAMSys/simulation/DRAMSys.h"
|
||||
|
||||
#include "DRAMSys/config/DRAMSysConfiguration.h"
|
||||
#include "DRAMSys/simulation/DRAMSys.h"
|
||||
|
||||
namespace DRAMSys
|
||||
{
|
||||
@@ -49,7 +48,7 @@ class DRAMSysRecordable : public DRAMSys
|
||||
{
|
||||
public:
|
||||
DRAMSysRecordable(const sc_core::sc_module_name& name,
|
||||
const ::DRAMSys::Config::Configuration& configLib);
|
||||
const Config::Configuration& configLib);
|
||||
|
||||
protected:
|
||||
void end_of_simulation() override;
|
||||
@@ -60,10 +59,7 @@ private:
|
||||
std::vector<TlmRecorder> tlmRecorders;
|
||||
|
||||
void setupTlmRecorders(const std::string& traceName,
|
||||
const ::DRAMSys::Config::Configuration& configLib);
|
||||
|
||||
void instantiateModules(const std::string& traceName,
|
||||
const ::DRAMSys::Config::Configuration& configLib);
|
||||
const Config::Configuration& configLib);
|
||||
};
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
71
src/libdramsys/DRAMSys/simulation/SimConfig.cpp
Normal file
71
src/libdramsys/DRAMSys/simulation/SimConfig.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2024, RPTU Kaiserslautern-Landau
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#include "SimConfig.h"
|
||||
#include "DRAMSys/config/SimConfig.h"
|
||||
|
||||
#include <systemc>
|
||||
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
SimConfig::SimConfig(const Config::SimConfig& simConfig) :
|
||||
simulationName(simConfig.SimulationName.value_or(DEFAULT_SIMULATION_NAME.data())),
|
||||
databaseRecording(simConfig.DatabaseRecording.value_or(DEFAULT_DATABASE_RECORDING)),
|
||||
powerAnalysis(simConfig.PowerAnalysis.value_or(DEFAULT_POWER_ANALYSIS)),
|
||||
enableWindowing(simConfig.EnableWindowing.value_or(DEFAULT_ENABLE_WINDOWING)),
|
||||
windowSize(simConfig.WindowSize.value_or(DEFAULT_WINDOW_SIZE)),
|
||||
debug(simConfig.Debug.value_or(DEFAULT_DEBUG)),
|
||||
simulationProgressBar(
|
||||
simConfig.SimulationProgressBar.value_or(DEFAULT_SIMULATION_PROGRESS_BAR)),
|
||||
checkTLM2Protocol(simConfig.CheckTLM2Protocol.value_or(DEFAULT_CHECK_TLM2_PROTOCOL)),
|
||||
useMalloc(simConfig.UseMalloc.value_or(DEFAULT_USE_MALLOC)),
|
||||
addressOffset(simConfig.AddressOffset.value_or(DEFAULT_ADDRESS_OFFSET)),
|
||||
storeMode(simConfig.StoreMode.value_or(DEFAULT_STORE_MODE))
|
||||
{
|
||||
if (storeMode == Config::StoreModeType::Invalid)
|
||||
SC_REPORT_FATAL("SimConfig", "Invalid StoreMode");
|
||||
|
||||
if (windowSize == 0)
|
||||
SC_REPORT_FATAL("SimConfig", "Minimum window size is 1");
|
||||
|
||||
#ifndef DRAMPOWER
|
||||
if (powerAnalysis)
|
||||
SC_REPORT_FATAL("SimConfig",
|
||||
"Power analysis is only supported with included DRAMPower library!");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace DRAMSys
|
||||
77
src/libdramsys/DRAMSys/simulation/SimConfig.h
Normal file
77
src/libdramsys/DRAMSys/simulation/SimConfig.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2024, RPTU Kaiserslautern-Landau
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors:
|
||||
* Derek Christ
|
||||
*/
|
||||
|
||||
#ifndef SIM_CONFIG_H
|
||||
#define SIM_CONFIG_H
|
||||
|
||||
#include <DRAMSys/config/SimConfig.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
struct SimConfig
|
||||
{
|
||||
SimConfig(const Config::SimConfig& simConfig);
|
||||
|
||||
std::string simulationName;
|
||||
bool databaseRecording;
|
||||
bool powerAnalysis;
|
||||
bool enableWindowing;
|
||||
unsigned int windowSize;
|
||||
bool debug;
|
||||
bool simulationProgressBar;
|
||||
bool checkTLM2Protocol;
|
||||
bool useMalloc;
|
||||
unsigned long long int addressOffset;
|
||||
Config::StoreModeType storeMode;
|
||||
|
||||
static constexpr std::string_view DEFAULT_SIMULATION_NAME = "default";
|
||||
static constexpr bool DEFAULT_DATABASE_RECORDING = false;
|
||||
static constexpr bool DEFAULT_POWER_ANALYSIS = false;
|
||||
static constexpr bool DEFAULT_ENABLE_WINDOWING = false;
|
||||
static constexpr unsigned int DEFAULT_WINDOW_SIZE = 1000;
|
||||
static constexpr bool DEFAULT_DEBUG = false;
|
||||
static constexpr bool DEFAULT_SIMULATION_PROGRESS_BAR = false;
|
||||
static constexpr bool DEFAULT_CHECK_TLM2_PROTOCOL = false;
|
||||
static constexpr bool DEFAULT_USE_MALLOC = false;
|
||||
static constexpr unsigned long long int DEFAULT_ADDRESS_OFFSET = 0;
|
||||
static constexpr Config::StoreModeType DEFAULT_STORE_MODE = Config::StoreModeType::NoStorage;
|
||||
};
|
||||
|
||||
} // namespace DRAMSys
|
||||
|
||||
#endif
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "Dram.h"
|
||||
|
||||
#include "DRAMSys/common/DebugManager.h"
|
||||
#include "DRAMSys/config/SimConfig.h"
|
||||
|
||||
#ifdef DRAMPOWER
|
||||
#include "LibDRAMPower.h"
|
||||
@@ -66,16 +67,15 @@ using namespace DRAMPower;
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
Dram::Dram(const sc_module_name& name, const Configuration& config) :
|
||||
Dram::Dram(const sc_module_name& name, const SimConfig& simConfig, const MemSpec& memSpec) :
|
||||
sc_module(name),
|
||||
memSpec(*config.memSpec),
|
||||
storeMode(config.storeMode),
|
||||
powerAnalysis(config.powerAnalysis),
|
||||
memSpec(memSpec),
|
||||
storeMode(simConfig.storeMode),
|
||||
powerAnalysis(simConfig.powerAnalysis),
|
||||
channelSize(memSpec.getSimMemSizeInBytes() / memSpec.numberOfChannels),
|
||||
useMalloc(config.useMalloc),
|
||||
tSocket("socket")
|
||||
useMalloc(simConfig.useMalloc)
|
||||
{
|
||||
if (storeMode == Configuration::StoreMode::Store)
|
||||
if (storeMode == Config::StoreModeType::Store)
|
||||
{
|
||||
if (useMalloc)
|
||||
{
|
||||
@@ -107,7 +107,6 @@ Dram::Dram(const sc_module_name& name, const Configuration& config) :
|
||||
#ifdef DRAMPOWER
|
||||
if (powerAnalysis)
|
||||
{
|
||||
const auto& memSpec = *config.memSpec;
|
||||
DRAMPower = std::make_unique<libDRAMPower>(memSpec.toDramPowerMemSpec(), false);
|
||||
}
|
||||
#endif
|
||||
@@ -149,7 +148,7 @@ tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload& trans, tlm_phase& phase
|
||||
}
|
||||
#endif
|
||||
|
||||
if (storeMode == Configuration::StoreMode::Store)
|
||||
if (storeMode == Config::StoreModeType::Store)
|
||||
{
|
||||
if (phase == BEGIN_RD || phase == BEGIN_RDA)
|
||||
{
|
||||
@@ -170,11 +169,11 @@ unsigned int Dram::transport_dbg(tlm_generic_payload& trans)
|
||||
PRINTDEBUGMESSAGE(name(), "transport_dgb");
|
||||
|
||||
// TODO: This part is not tested yet, neither with traceplayers nor with GEM5 coupling
|
||||
if (storeMode == Configuration::StoreMode::NoStorage)
|
||||
if (storeMode == Config::StoreModeType::NoStorage)
|
||||
{
|
||||
SC_REPORT_FATAL("DRAM", "Debug Transport is used in combination with NoStorage");
|
||||
}
|
||||
else if (storeMode == Configuration::StoreMode::Store)
|
||||
else if (storeMode == Config::StoreModeType::Store)
|
||||
{
|
||||
if (trans.is_read())
|
||||
{
|
||||
@@ -184,7 +183,7 @@ unsigned int Dram::transport_dbg(tlm_generic_payload& trans)
|
||||
{
|
||||
executeWrite(trans);
|
||||
}
|
||||
|
||||
|
||||
return trans.get_data_length();
|
||||
}
|
||||
|
||||
@@ -201,7 +200,7 @@ void Dram::b_transport(tlm_generic_payload& trans, [[maybe_unused]] sc_time& del
|
||||
printedWarning = true;
|
||||
}
|
||||
|
||||
if (storeMode == Configuration::StoreMode::Store)
|
||||
if (storeMode == Config::StoreModeType::Store)
|
||||
{
|
||||
if (trans.is_read())
|
||||
{
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
|
||||
#include "DRAMSys/common/Deserialize.h"
|
||||
#include "DRAMSys/common/Serialize.h"
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "DRAMSys/configuration/memspec/MemSpec.h"
|
||||
#include "DRAMSys/simulation/SimConfig.h"
|
||||
|
||||
#include <memory>
|
||||
#include <systemc>
|
||||
@@ -62,7 +62,7 @@ protected:
|
||||
const MemSpec& memSpec;
|
||||
|
||||
// Data Storage:
|
||||
const Configuration::StoreMode storeMode;
|
||||
const Config::StoreModeType storeMode;
|
||||
const bool powerAnalysis;
|
||||
unsigned char* memory;
|
||||
const uint64_t channelSize;
|
||||
@@ -82,7 +82,7 @@ protected:
|
||||
void executeWrite(const tlm::tlm_generic_payload& trans);
|
||||
|
||||
public:
|
||||
Dram(const sc_core::sc_module_name& name, const Configuration& config);
|
||||
Dram(const sc_core::sc_module_name& name, const SimConfig& simConfig, const MemSpec& memSpec);
|
||||
SC_HAS_PROCESS(Dram);
|
||||
|
||||
Dram(const Dram&) = delete;
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
"Use the blocking mode of DRAMSys with caution! "
|
||||
"The simulated timings do not reflect the real system!";
|
||||
|
||||
tlm_utils::simple_target_socket<Dram> tSocket;
|
||||
tlm_utils::simple_target_socket<Dram> tSocket{"tSocket"};
|
||||
|
||||
virtual void reportPower();
|
||||
|
||||
|
||||
@@ -46,16 +46,17 @@ namespace DRAMSys
|
||||
{
|
||||
|
||||
DramRecordable::DramRecordable(const sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const SimConfig& simConfig,
|
||||
const MemSpec& memSpec,
|
||||
TlmRecorder& tlmRecorder) :
|
||||
Dram(name, config),
|
||||
Dram(name, simConfig, memSpec),
|
||||
tlmRecorder(tlmRecorder),
|
||||
powerWindowSize(config.memSpec->tCK * config.windowSize)
|
||||
powerWindowSize(memSpec.tCK * simConfig.windowSize)
|
||||
{
|
||||
#ifdef DRAMPOWER
|
||||
// Create a thread that is triggered every $powerWindowSize
|
||||
// to generate a Power over Time plot in the Trace analyzer:
|
||||
if (config.powerAnalysis && config.enableWindowing)
|
||||
if (simConfig.powerAnalysis && simConfig.enableWindowing)
|
||||
SC_THREAD(powerWindow);
|
||||
#endif
|
||||
}
|
||||
@@ -70,9 +71,8 @@ void DramRecordable::reportPower()
|
||||
#endif
|
||||
}
|
||||
|
||||
tlm_sync_enum DramRecordable::nb_transport_fw(tlm_generic_payload& trans,
|
||||
tlm_phase& phase,
|
||||
sc_time& delay)
|
||||
tlm_sync_enum
|
||||
DramRecordable::nb_transport_fw(tlm_generic_payload& trans, tlm_phase& phase, sc_time& delay)
|
||||
{
|
||||
tlmRecorder.recordPhase(trans, phase, delay);
|
||||
return Dram::nb_transport_fw(trans, phase, delay);
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#define DRAMRECORDABLE_H
|
||||
|
||||
#include "DRAMSys/common/TlmRecorder.h"
|
||||
#include "DRAMSys/configuration/Configuration.h"
|
||||
#include "Dram.h"
|
||||
|
||||
#ifdef DRAMPOWER
|
||||
@@ -54,7 +53,8 @@ class DramRecordable : public Dram
|
||||
{
|
||||
public:
|
||||
DramRecordable(const sc_core::sc_module_name& name,
|
||||
const Configuration& config,
|
||||
const SimConfig& simConfig,
|
||||
const MemSpec& memSpec,
|
||||
TlmRecorder& tlmRecorder);
|
||||
SC_HAS_PROCESS(DramRecordable);
|
||||
|
||||
@@ -72,7 +72,7 @@ private:
|
||||
// When working with floats, we have to decide ourselves what is an
|
||||
// acceptable definition for "equal". Here the number is compared with a
|
||||
// suitable error margin (0.00001).
|
||||
bool isEqual(double a, double b, const double epsilon = 1e-05)
|
||||
static bool isEqual(double a, double b, const double epsilon = 1e-05)
|
||||
{
|
||||
return std::fabs(a - b) < epsilon;
|
||||
}
|
||||
|
||||
@@ -88,8 +88,8 @@ Simulator::Simulator(DRAMSys::Config::Configuration configuration,
|
||||
std::unique_ptr<Initiator>
|
||||
Simulator::instantiateInitiator(const DRAMSys::Config::Initiator& initiator)
|
||||
{
|
||||
uint64_t memorySize = dramSys->getConfig().memSpec->getSimMemSizeInBytes();
|
||||
unsigned int defaultDataLength = dramSys->getConfig().memSpec->defaultBytesPerBurst;
|
||||
uint64_t memorySize = dramSys->getMemSpec().getSimMemSizeInBytes();
|
||||
unsigned int defaultDataLength = dramSys->getMemSpec().defaultBytesPerBurst;
|
||||
|
||||
return std::visit(
|
||||
[=](auto&& config) -> std::unique_ptr<Initiator>
|
||||
|
||||
Reference in New Issue
Block a user