Format all files

This commit is contained in:
2023-08-29 09:26:25 +02:00
parent 25c729de1d
commit c07d09f392
283 changed files with 10375 additions and 8412 deletions

View File

@@ -78,6 +78,6 @@ NLOHMANN_JSONIFY_ALL_THINGS(AddressMapping,
CHANNEL_BIT,
XOR)
} // namespace Configuration
} // namespace DRAMSys::Config
#endif // DRAMSYSCONFIGURATION_ADDRESSMAPPING_H

View File

@@ -57,17 +57,18 @@ Configuration from_path(std::string_view path, std::string_view resourceDirector
// This custom parser callback is responsible to swap out the paths to the sub-config json files
// with the actual json data.
std::function<bool(int depth, nlohmann::detail::parse_event_t event, json_t &parsed)>
std::function<bool(int depth, nlohmann::detail::parse_event_t event, json_t& parsed)>
parser_callback;
parser_callback =
[&parser_callback, &current_sub_config, resourceDirectory](
int depth, nlohmann::detail::parse_event_t event, json_t &parsed) -> bool {
parser_callback = [&parser_callback, &current_sub_config, resourceDirectory](
int depth, nlohmann::detail::parse_event_t event, json_t& parsed) -> bool
{
using nlohmann::detail::parse_event_t;
if (depth != 2)
return true;
if (event == parse_event_t::key) {
if (event == parse_event_t::key)
{
assert(parsed.is_string());
if (parsed == MemSpec::KEY)
@@ -86,12 +87,14 @@ Configuration from_path(std::string_view path, std::string_view resourceDirector
// In case we have an value (string) instead of an object, replace the value with the loaded
// json object.
if (event == parse_event_t::value && current_sub_config != SubConfig::Unkown) {
if (event == parse_event_t::value && current_sub_config != SubConfig::Unkown)
{
// Replace name of json file with actual json data
auto parse_json = [&parser_callback,
resourceDirectory](std::string_view base_dir,
std::string_view sub_config_key,
const std::string &filename) -> json_t {
const std::string& filename) -> json_t
{
std::filesystem::path path(resourceDirectory);
path /= base_dir;
path /= filename;
@@ -121,7 +124,8 @@ Configuration from_path(std::string_view path, std::string_view resourceDirector
return true;
};
if (file.is_open()) {
if (file.is_open())
{
json_t simulation = json_t::parse(file, parser_callback, true, true).at(Configuration::KEY);
return simulation.get<DRAMSys::Config::Configuration>();
}

View File

@@ -57,7 +57,8 @@
* with the actual json object that is stored at this path.
*/
namespace DRAMSys::Config {
namespace DRAMSys::Config
{
struct Configuration
{
@@ -71,15 +72,11 @@ struct Configuration
std::optional<std::vector<Initiator>> tracesetup;
};
NLOHMANN_JSONIFY_ALL_THINGS(Configuration,
addressmapping,
mcconfig,
memspec,
simconfig,
simulationid,
tracesetup)
NLOHMANN_JSONIFY_ALL_THINGS(
Configuration, addressmapping, mcconfig, memspec, simconfig, simulationid, tracesetup)
Configuration from_path(std::string_view path, std::string_view resourceDirectory = DRAMSYS_RESOURCE_DIR);
Configuration from_path(std::string_view path,
std::string_view resourceDirectory = DRAMSYS_RESOURCE_DIR);
} // namespace DRAMSys::Config

View File

@@ -39,8 +39,8 @@
#include "DRAMSys/util/json.h"
#include <optional>
#include <utility>
#include <string>
#include <utility>
namespace DRAMSys::Config
{
@@ -54,13 +54,14 @@ enum class PagePolicyType
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(PagePolicyType, {
{PagePolicyType::Invalid, nullptr},
{PagePolicyType::Open, "Open"},
{PagePolicyType::OpenAdaptive, "OpenAdaptive"},
{PagePolicyType::Closed, "Closed"},
{PagePolicyType::ClosedAdaptive, "ClosedAdaptive"},
})
NLOHMANN_JSON_SERIALIZE_ENUM(PagePolicyType,
{
{PagePolicyType::Invalid, nullptr},
{PagePolicyType::Open, "Open"},
{PagePolicyType::OpenAdaptive, "OpenAdaptive"},
{PagePolicyType::Closed, "Closed"},
{PagePolicyType::ClosedAdaptive, "ClosedAdaptive"},
})
enum class SchedulerType
{
@@ -72,12 +73,13 @@ enum class SchedulerType
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(SchedulerType, {{SchedulerType::Invalid, nullptr},
{SchedulerType::Fifo, "Fifo"},
{SchedulerType::FrFcfs, "FrFcfs"},
{SchedulerType::FrFcfsGrp, "FrFcfsGrp"},
{SchedulerType::GrpFrFcfs, "GrpFrFcfs"},
{SchedulerType::GrpFrFcfsWm, "GrpFrFcfsWm"}})
NLOHMANN_JSON_SERIALIZE_ENUM(SchedulerType,
{{SchedulerType::Invalid, nullptr},
{SchedulerType::Fifo, "Fifo"},
{SchedulerType::FrFcfs, "FrFcfs"},
{SchedulerType::FrFcfsGrp, "FrFcfsGrp"},
{SchedulerType::GrpFrFcfs, "GrpFrFcfs"},
{SchedulerType::GrpFrFcfsWm, "GrpFrFcfsWm"}})
enum class SchedulerBufferType
{
@@ -87,10 +89,11 @@ enum class SchedulerBufferType
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(SchedulerBufferType, {{SchedulerBufferType::Invalid, nullptr},
{SchedulerBufferType::Bankwise, "Bankwise"},
{SchedulerBufferType::ReadWrite, "ReadWrite"},
{SchedulerBufferType::Shared, "Shared"}})
NLOHMANN_JSON_SERIALIZE_ENUM(SchedulerBufferType,
{{SchedulerBufferType::Invalid, nullptr},
{SchedulerBufferType::Bankwise, "Bankwise"},
{SchedulerBufferType::ReadWrite, "ReadWrite"},
{SchedulerBufferType::Shared, "Shared"}})
enum class CmdMuxType
{
@@ -100,7 +103,9 @@ enum class CmdMuxType
};
NLOHMANN_JSON_SERIALIZE_ENUM(CmdMuxType,
{{CmdMuxType::Invalid, nullptr}, {CmdMuxType::Oldest, "Oldest"}, {CmdMuxType::Strict, "Strict"}})
{{CmdMuxType::Invalid, nullptr},
{CmdMuxType::Oldest, "Oldest"},
{CmdMuxType::Strict, "Strict"}})
enum class RespQueueType
{
@@ -109,9 +114,10 @@ enum class RespQueueType
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(RespQueueType, {{RespQueueType::Invalid, nullptr},
{RespQueueType::Fifo, "Fifo"},
{RespQueueType::Reorder, "Reorder"}})
NLOHMANN_JSON_SERIALIZE_ENUM(RespQueueType,
{{RespQueueType::Invalid, nullptr},
{RespQueueType::Fifo, "Fifo"},
{RespQueueType::Reorder, "Reorder"}})
enum class RefreshPolicyType
{
@@ -123,18 +129,19 @@ enum class RefreshPolicyType
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(RefreshPolicyType, {{RefreshPolicyType::Invalid, nullptr},
{RefreshPolicyType::NoRefresh, "NoRefresh"},
{RefreshPolicyType::AllBank, "AllBank"},
{RefreshPolicyType::PerBank, "PerBank"},
{RefreshPolicyType::Per2Bank, "Per2Bank"},
{RefreshPolicyType::SameBank, "SameBank"},
NLOHMANN_JSON_SERIALIZE_ENUM(RefreshPolicyType,
{{RefreshPolicyType::Invalid, nullptr},
{RefreshPolicyType::NoRefresh, "NoRefresh"},
{RefreshPolicyType::AllBank, "AllBank"},
{RefreshPolicyType::PerBank, "PerBank"},
{RefreshPolicyType::Per2Bank, "Per2Bank"},
{RefreshPolicyType::SameBank, "SameBank"},
// Alternative conversions to provide backwards-compatibility
// when deserializing. Will not be used for serializing.
{RefreshPolicyType::AllBank, "Rankwise"},
{RefreshPolicyType::PerBank, "Bankwise"},
{RefreshPolicyType::SameBank, "Groupwise"}})
// Alternative conversions to provide backwards-compatibility
// when deserializing. Will not be used for serializing.
{RefreshPolicyType::AllBank, "Rankwise"},
{RefreshPolicyType::PerBank, "Bankwise"},
{RefreshPolicyType::SameBank, "Groupwise"}})
enum class PowerDownPolicyType
{
@@ -143,9 +150,10 @@ enum class PowerDownPolicyType
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(PowerDownPolicyType, {{PowerDownPolicyType::Invalid, nullptr},
{PowerDownPolicyType::NoPowerDown, "NoPowerDown"},
{PowerDownPolicyType::Staggered, "Staggered"}})
NLOHMANN_JSON_SERIALIZE_ENUM(PowerDownPolicyType,
{{PowerDownPolicyType::Invalid, nullptr},
{PowerDownPolicyType::NoPowerDown, "NoPowerDown"},
{PowerDownPolicyType::Staggered, "Staggered"}})
enum class ArbiterType
{
@@ -155,10 +163,11 @@ enum class ArbiterType
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(ArbiterType, {{ArbiterType::Invalid, nullptr},
{ArbiterType::Simple, "Simple"},
{ArbiterType::Fifo, "Fifo"},
{ArbiterType::Reorder, "Reorder"}})
NLOHMANN_JSON_SERIALIZE_ENUM(ArbiterType,
{{ArbiterType::Invalid, nullptr},
{ArbiterType::Simple, "Simple"},
{ArbiterType::Fifo, "Fifo"},
{ArbiterType::Reorder, "Reorder"}})
struct McConfig
{
@@ -215,6 +224,6 @@ NLOHMANN_JSONIFY_ALL_THINGS(McConfig,
BlockingReadDelay,
BlockingWriteDelay)
} // namespace Configuration
} // namespace DRAMSys::Config
#endif // DRAMSYSCONFIGURATION_MCCONFIG_H

View File

@@ -51,10 +51,11 @@ enum class StoreModeType
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(StoreModeType, {{StoreModeType::Invalid, nullptr},
{StoreModeType::NoStorage, "NoStorage"},
{StoreModeType::Store, "Store"},
{StoreModeType::ErrorModel, "ErrorModel"}})
NLOHMANN_JSON_SERIALIZE_ENUM(StoreModeType,
{{StoreModeType::Invalid, nullptr},
{StoreModeType::NoStorage, "NoStorage"},
{StoreModeType::Store, "Store"},
{StoreModeType::ErrorModel, "ErrorModel"}})
struct SimConfig
{
@@ -93,6 +94,6 @@ NLOHMANN_JSONIFY_ALL_THINGS(SimConfig,
UseMalloc,
WindowSize)
} // namespace Configuration
} // namespace DRAMSys::Config
#endif // DRAMSYSCONFIGURATION_SIMCONFIG_H

View File

@@ -52,10 +52,11 @@ enum class TrafficInitiatorType
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(TrafficInitiatorType, {{TrafficInitiatorType::Invalid, nullptr},
{TrafficInitiatorType::Player, "player"},
{TrafficInitiatorType::Hammer, "hammer"},
{TrafficInitiatorType::Generator, "generator"}})
NLOHMANN_JSON_SERIALIZE_ENUM(TrafficInitiatorType,
{{TrafficInitiatorType::Invalid, nullptr},
{TrafficInitiatorType::Player, "player"},
{TrafficInitiatorType::Hammer, "hammer"},
{TrafficInitiatorType::Generator, "generator"}})
enum class AddressDistribution
{
@@ -64,9 +65,10 @@ enum class AddressDistribution
Invalid = -1
};
NLOHMANN_JSON_SERIALIZE_ENUM(AddressDistribution, {{AddressDistribution::Invalid, nullptr},
{AddressDistribution::Random, "random"},
{AddressDistribution::Sequential, "sequential"}})
NLOHMANN_JSON_SERIALIZE_ENUM(AddressDistribution,
{{AddressDistribution::Invalid, nullptr},
{AddressDistribution::Random, "random"},
{AddressDistribution::Sequential, "sequential"}})
struct TracePlayer
{
@@ -192,8 +194,13 @@ struct RowHammer
uint64_t rowIncrement{};
};
NLOHMANN_JSONIFY_ALL_THINGS(
RowHammer, clkMhz, name, maxPendingReadRequests, maxPendingWriteRequests, numRequests, rowIncrement)
NLOHMANN_JSONIFY_ALL_THINGS(RowHammer,
clkMhz,
name,
maxPendingReadRequests,
maxPendingWriteRequests,
numRequests,
rowIncrement)
struct TraceSetupConstants
{
@@ -201,8 +208,9 @@ struct TraceSetupConstants
static constexpr std::string_view SUB_DIR = "tracesetup";
};
using Initiator = std::variant<TracePlayer, TrafficGenerator, TrafficGeneratorStateMachine, RowHammer>;
using Initiator =
std::variant<TracePlayer, TrafficGenerator, TrafficGeneratorStateMachine, RowHammer>;
} // namespace Configuration
} // namespace DRAMSys::Config
#endif // DRAMSYSCONFIGURATION_TRACESETUP_H

View File

@@ -38,22 +38,22 @@
namespace DRAMSys::Config
{
void to_json(json_t &j, const MemArchitectureSpecType &c)
void to_json(json_t& j, const MemArchitectureSpecType& c)
{
j = json_t{};
for (const auto &entry : c.entries)
for (const auto& entry : c.entries)
{
j[entry.first] = entry.second;
}
}
void from_json(const json_t &j, MemArchitectureSpecType &c)
void from_json(const json_t& j, MemArchitectureSpecType& c)
{
for (const auto &entry : j.items())
for (const auto& entry : j.items())
{
c.entries[entry.key()] = entry.value();
}
}
} // namespace Configuration
} // namespace DRAMSys::Config

View File

@@ -48,9 +48,9 @@ struct MemArchitectureSpecType
std::unordered_map<std::string, unsigned int> entries;
};
void to_json(json_t &j, const MemArchitectureSpecType &c);
void from_json(const json_t &j, MemArchitectureSpecType &c);
void to_json(json_t& j, const MemArchitectureSpecType& c);
void from_json(const json_t& j, MemArchitectureSpecType& c);
} // namespace Configuration
} // namespace DRAMSys::Config
#endif // DRAMSYSCONFIGURATION_MEMARCHITECTURESPEC_H

View File

@@ -38,22 +38,22 @@
namespace DRAMSys::Config
{
void to_json(json_t &j, const MemPowerSpec &c)
void to_json(json_t& j, const MemPowerSpec& c)
{
j = json_t{};
for (const auto &entry : c.entries)
for (const auto& entry : c.entries)
{
j[entry.first] = entry.second;
}
}
void from_json(const json_t &j, MemPowerSpec &c)
void from_json(const json_t& j, MemPowerSpec& c)
{
for (const auto &entry : j.items())
for (const auto& entry : j.items())
{
c.entries[entry.key()] = entry.value();
}
}
} // namespace Configuration
} // namespace DRAMSys::Config

View File

@@ -48,9 +48,9 @@ struct MemPowerSpec
std::unordered_map<std::string, double> entries;
};
void to_json(json_t &j, const MemPowerSpec &c);
void from_json(const json_t &j, MemPowerSpec &c);
void to_json(json_t& j, const MemPowerSpec& c);
void from_json(const json_t& j, MemPowerSpec& c);
} // namespace Configuration
} // namespace DRAMSys::Config
#endif // DRAMSYSCONFIGURATION_MEMPOWERSPEC_H

View File

@@ -36,14 +36,15 @@
#ifndef DRAMSYSCONFIGURATION_MEMSPEC_H
#define DRAMSYSCONFIGURATION_MEMSPEC_H
#include "DRAMSys/util/json.h"
#include "DRAMSys/config/memspec/MemArchitectureSpec.h"
#include "DRAMSys/config/memspec/MemPowerSpec.h"
#include "DRAMSys/config/memspec/MemTimingSpec.h"
#include "DRAMSys/util/json.h"
#include <optional>
namespace DRAMSys::Config {
namespace DRAMSys::Config
{
struct MemSpec
{
@@ -60,6 +61,6 @@ struct MemSpec
NLOHMANN_JSONIFY_ALL_THINGS(
MemSpec, memarchitecturespec, memoryId, memoryType, memtimingspec, mempowerspec)
} // namespace Configuration
} // namespace DRAMSys::Config
#endif // DRAMSYSCONFIGURATION_MEMSPEC_H

View File

@@ -38,22 +38,22 @@
namespace DRAMSys::Config
{
void to_json(json_t &j, const MemTimingSpecType &c)
void to_json(json_t& j, const MemTimingSpecType& c)
{
j = json_t{};
for (const auto &entry : c.entries)
for (const auto& entry : c.entries)
{
j[entry.first] = entry.second;
}
}
void from_json(const json_t &j, MemTimingSpecType &c)
void from_json(const json_t& j, MemTimingSpecType& c)
{
for (const auto &entry : j.items())
for (const auto& entry : j.items())
{
c.entries[entry.key()] = entry.value();
}
}
} // namespace Configuration
} // namespace DRAMSys::Config

View File

@@ -49,9 +49,9 @@ struct MemTimingSpecType
std::unordered_map<std::string, unsigned int> entries;
};
void to_json(json &j, const MemTimingSpecType &c);
void from_json(const json &j, MemTimingSpecType &c);
void to_json(json& j, const MemTimingSpecType& c);
void from_json(const json& j, MemTimingSpecType& c);
} // namespace Configuration
} // namespace DRAMSys::Config
#endif // DRAMSYSCONFIGURATION_MEMTIMINGSPEC_H

View File

@@ -43,15 +43,17 @@
namespace DRAMSys
{
void DebugManager::printDebugMessage(const std::string &sender, const std::string &message)
void DebugManager::printDebugMessage(const std::string& sender, const std::string& message)
{
if (debugEnabled)
{
if (writeToConsole)
std::cout << " at " << sc_core::sc_time_stamp() << "\t in " << sender << "\t: " << message << std::endl;
std::cout << " at " << sc_core::sc_time_stamp() << "\t in " << sender
<< "\t: " << message << std::endl;
if (writeToFile && debugFile)
debugFile << " at " << sc_core::sc_time_stamp() << "\t in " << sender << "\t: " << message << std::endl;
debugFile << " at " << sc_core::sc_time_stamp() << "\t in " << sender
<< "\t: " << message << std::endl;
}
}
@@ -62,12 +64,13 @@ void DebugManager::setup(bool _debugEnabled, bool _writeToConsole, bool _writeTo
writeToFile = _writeToFile;
}
void DebugManager::printMessage(const std::string &sender, const std::string &message)
void DebugManager::printMessage(const std::string& sender, const std::string& message)
{
std::cout << " at " << sc_core::sc_time_stamp() << "\t in " << sender << "\t: " << message << std::endl;
std::cout << " at " << sc_core::sc_time_stamp() << "\t in " << sender << "\t: " << message
<< std::endl;
}
void DebugManager::openDebugFile(const std::string &filename)
void DebugManager::openDebugFile(const std::string& filename)
{
if (debugFile)
debugFile.close();

View File

@@ -38,12 +38,15 @@
#define DEBUGMANAGER_H
#ifdef NDEBUG
#define PRINTDEBUGMESSAGE(sender, message) {}
#define PRINTDEBUGMESSAGE(sender, message) \
{ \
}
#else
#define PRINTDEBUGMESSAGE(sender, message) DebugManager::getInstance().printDebugMessage(sender, message)
#define PRINTDEBUGMESSAGE(sender, message) \
DebugManager::getInstance().printDebugMessage(sender, message)
#include <string>
#include <fstream>
#include <string>
namespace DRAMSys
{
@@ -51,7 +54,7 @@ namespace DRAMSys
class DebugManager
{
public:
static DebugManager &getInstance()
static DebugManager& getInstance()
{
static DebugManager _instance;
return _instance;
@@ -69,9 +72,9 @@ public:
void setup(bool _debugEnabled, bool _writeToConsole, bool _writeToFile);
void printDebugMessage(const std::string &sender, const std::string &message);
static void printMessage(const std::string &sender, const std::string &message);
void openDebugFile(const std::string &filename);
void printDebugMessage(const std::string& sender, const std::string& message);
static void printMessage(const std::string& sender, const std::string& message);
void openDebugFile(const std::string& filename);
private:
bool debugEnabled = false;

View File

@@ -52,9 +52,9 @@ using namespace tlm;
namespace DRAMSys
{
TlmRecorder::TlmRecorder(const std::string &name,
const Configuration &config,
const std::string &dbName) :
TlmRecorder::TlmRecorder(const std::string& name,
const Configuration& config,
const std::string& dbName) :
name(name),
config(config),
memSpec(*config.memSpec),
@@ -66,7 +66,7 @@ TlmRecorder::TlmRecorder(const std::string &name,
storageDataBuffer->reserve(transactionCommitRate);
openDB(dbName);
char *sErrMsg = nullptr;
char* sErrMsg = nullptr;
sqlite3_exec(db, "PRAGMA main.page_size = 4096", nullptr, nullptr, &sErrMsg);
sqlite3_exec(db, "PRAGMA main.cache_size=10000", nullptr, nullptr, &sErrMsg);
sqlite3_exec(db, "PRAGMA main.locking_mode=EXCLUSIVE", nullptr, nullptr, &sErrMsg);
@@ -106,7 +106,8 @@ void TlmRecorder::recordPower(double timeInSeconds, double averagePower)
executeSqlStatement(insertPowerStatement);
}
void TlmRecorder::recordBufferDepth(double timeInSeconds, const std::vector<double> &averageBufferDepth)
void TlmRecorder::recordBufferDepth(double timeInSeconds,
const std::vector<double>& averageBufferDepth)
{
for (size_t index = 0; index < averageBufferDepth.size(); index++)
{
@@ -124,7 +125,9 @@ void TlmRecorder::recordBandwidth(double timeInSeconds, double averageBandwidth)
executeSqlStatement(insertBandwidthStatement);
}
void TlmRecorder::recordPhase(tlm_generic_payload& trans, const tlm_phase& phase, const sc_time& delay)
void TlmRecorder::recordPhase(tlm_generic_payload& trans,
const tlm_phase& phase,
const sc_time& delay)
{
const sc_time& currentTime = sc_time_stamp();
@@ -132,22 +135,26 @@ void TlmRecorder::recordPhase(tlm_generic_payload& trans, const tlm_phase& phase
{
introduceTransactionToSystem(trans);
std::string phaseName = getPhaseName(phase).substr(6);
currentTransactionsInSystem.at(&trans).recordedPhases.emplace_back(phaseName, currentTime + delay);
currentTransactionsInSystem.at(&trans).recordedPhases.emplace_back(phaseName,
currentTime + delay);
}
if (phase == BEGIN_RESP)
{
std::string phaseName = getPhaseName(phase).substr(6);
currentTransactionsInSystem.at(&trans).recordedPhases.emplace_back(phaseName, currentTime + delay);
currentTransactionsInSystem.at(&trans).recordedPhases.emplace_back(phaseName,
currentTime + delay);
}
else if (phase == END_REQ)
{
// BEGIN_REQ is always the first phase of a normal transaction
currentTransactionsInSystem.at(&trans).recordedPhases.front().interval.end = currentTime + delay;
currentTransactionsInSystem.at(&trans).recordedPhases.front().interval.end =
currentTime + delay;
}
else if (phase == END_RESP)
{
// BEGIN_RESP is always the last phase of a normal transaction at this point
currentTransactionsInSystem.at(&trans).recordedPhases.back().interval.end = currentTime + delay;
currentTransactionsInSystem.at(&trans).recordedPhases.back().interval.end =
currentTime + delay;
removeTransactionFromSystem(trans);
}
else if (isFixedCommandPhase(phase))
@@ -174,11 +181,18 @@ void TlmRecorder::recordPhase(tlm_generic_payload& trans, const tlm_phase& phase
intervalOnDataStrobe.end = currentTime + intervalOnDataStrobe.end;
}
currentTransactionsInSystem.at(keyTrans).recordedPhases.emplace_back(std::move(phaseName),
std::move(TimeInterval(currentTime + delay,
currentTime + delay + memSpec.getExecutionTime(Command(phase), trans))),
std::move(intervalOnDataStrobe), extension.getRank(), extension.getBankGroup(), extension.getBank(),
extension.getRow(), extension.getColumn(), extension.getBurstLength());
currentTransactionsInSystem.at(keyTrans).recordedPhases.emplace_back(
std::move(phaseName),
std::move(TimeInterval(currentTime + delay,
currentTime + delay +
memSpec.getExecutionTime(Command(phase), trans))),
std::move(intervalOnDataStrobe),
extension.getRank(),
extension.getBankGroup(),
extension.getBank(),
extension.getRow(),
extension.getColumn(),
extension.getBurstLength());
if (isRefreshCommandPhase(phase))
removeTransactionFromSystem(trans);
@@ -188,28 +202,32 @@ void TlmRecorder::recordPhase(tlm_generic_payload& trans, const tlm_phase& phase
introduceTransactionToSystem(trans);
std::string phaseName = getPhaseName(phase).substr(6); // remove "BEGIN_"
const ControllerExtension& extension = ControllerExtension::getExtension(trans);
currentTransactionsInSystem.at(&trans).recordedPhases.emplace_back(std::move(phaseName),
std::move(TimeInterval(currentTime + delay, SC_ZERO_TIME)),
std::move(TimeInterval(SC_ZERO_TIME, SC_ZERO_TIME)),
extension.getRank(), extension.getBankGroup(), extension.getBank(),
extension.getRow(), extension.getColumn(), extension.getBurstLength());
currentTransactionsInSystem.at(&trans).recordedPhases.emplace_back(
std::move(phaseName),
std::move(TimeInterval(currentTime + delay, SC_ZERO_TIME)),
std::move(TimeInterval(SC_ZERO_TIME, SC_ZERO_TIME)),
extension.getRank(),
extension.getBankGroup(),
extension.getBank(),
extension.getRow(),
extension.getColumn(),
extension.getBurstLength());
}
else if (isPowerDownExitPhase(phase))
{
currentTransactionsInSystem.at(&trans).recordedPhases.back().interval.end = currentTime + delay
+ memSpec.getCommandLength(Command(phase));
currentTransactionsInSystem.at(&trans).recordedPhases.back().interval.end =
currentTime + delay + memSpec.getCommandLength(Command(phase));
removeTransactionFromSystem(trans);
}
simulationTimeCoveredByRecording = currentTime + delay;
}
void TlmRecorder::recordDebugMessage(const std::string &message, const sc_time &time)
void TlmRecorder::recordDebugMessage(const std::string& message, const sc_time& time)
{
insertDebugMessageInDB(message, time);
}
// ------------- internal -----------------------
void TlmRecorder::introduceTransactionToSystem(tlm_generic_payload& trans)
@@ -227,20 +245,27 @@ void TlmRecorder::introduceTransactionToSystem(tlm_generic_payload& trans)
const ArbiterExtension& extension = ArbiterExtension::getExtension(trans);
currentTransactionsInSystem.insert({&trans, Transaction(totalNumTransactions, trans.get_address(),
trans.get_data_length(), commandChar, extension.getTimeOfGeneration(), extension.getThread(),
extension.getChannel())});
currentTransactionsInSystem.insert({&trans,
Transaction(totalNumTransactions,
trans.get_address(),
trans.get_data_length(),
commandChar,
extension.getTimeOfGeneration(),
extension.getThread(),
extension.getChannel())});
PRINTDEBUGMESSAGE(name, "New transaction #" + std::to_string(totalNumTransactions) + " generation time " +
currentTransactionsInSystem.at(&trans).timeOfGeneration.to_string());
PRINTDEBUGMESSAGE(name,
"New transaction #" + std::to_string(totalNumTransactions) +
" generation time " +
currentTransactionsInSystem.at(&trans).timeOfGeneration.to_string());
}
void TlmRecorder::removeTransactionFromSystem(tlm_generic_payload &trans)
void TlmRecorder::removeTransactionFromSystem(tlm_generic_payload& trans)
{
assert(currentTransactionsInSystem.count(&trans) != 0);
PRINTDEBUGMESSAGE(name, "Removing transaction #" +
std::to_string(currentTransactionsInSystem.at(&trans).id));
PRINTDEBUGMESSAGE(
name, "Removing transaction #" + std::to_string(currentTransactionsInSystem.at(&trans).id));
Transaction& recordingData = currentTransactionsInSystem.at(&trans);
currentDataBuffer->push_back(recordingData);
@@ -256,16 +281,18 @@ void TlmRecorder::removeTransactionFromSystem(tlm_generic_payload &trans)
storageThread = std::thread(&TlmRecorder::commitRecordedDataToDB, this);
currentDataBuffer->clear();
}
}
void TlmRecorder::terminateRemainingTransactions()
{
while (!currentTransactionsInSystem.empty())
{
auto transaction = std::min_element(currentTransactionsInSystem.begin(),
currentTransactionsInSystem.end(), [](decltype(currentTransactionsInSystem)::value_type& l,
decltype(currentTransactionsInSystem)::value_type& r) -> bool {return l.second.id < r.second.id;});
auto transaction =
std::min_element(currentTransactionsInSystem.begin(),
currentTransactionsInSystem.end(),
[](decltype(currentTransactionsInSystem)::value_type& l,
decltype(currentTransactionsInSystem)::value_type& r) -> bool
{ return l.second.id < r.second.id; });
if (transaction->second.cmd == 'X')
{
std::string beginPhase = transaction->second.recordedPhases.front().name;
@@ -289,7 +316,8 @@ void TlmRecorder::terminateRemainingTransactions()
// Do not terminate transaction as it is not ready to be completed.
currentTransactionsInSystem.erase(transaction);
// Decrement totalNumTransactions as this transaction will not be recorded in the database.
// Decrement totalNumTransactions as this transaction will not be recorded in the
// database.
totalNumTransactions--;
}
}
@@ -320,7 +348,7 @@ void TlmRecorder::commitRecordedDataToDB()
sqlite3_exec(db, "COMMIT;", nullptr, nullptr, nullptr);
}
void TlmRecorder::openDB(const std::string &dbName)
void TlmRecorder::openDB(const std::string& dbName)
{
std::ifstream f(dbName.c_str());
if (f.good())
@@ -341,85 +369,114 @@ void TlmRecorder::openDB(const std::string &dbName)
void TlmRecorder::prepareSqlStatements()
{
insertTransactionString =
"INSERT INTO Transactions VALUES (:id,:rangeID,:address,:dataLength,:thread,:channel,"
":timeOfGeneration,:command)";
"INSERT INTO Transactions VALUES (:id,:rangeID,:address,:dataLength,:thread,:channel,"
":timeOfGeneration,:command)";
insertRangeString = "INSERT INTO Ranges VALUES (:id,:begin,:end)";
updateRangeString = "UPDATE Ranges SET End = :end WHERE ID = :id";
insertPhaseString =
"INSERT INTO Phases (PhaseName,PhaseBegin,PhaseEnd,DataStrobeBegin,DataStrobeEnd,Rank,BankGroup,Bank,"
"Row,Column,BurstLength,Transact) VALUES (:name,:begin,:end,:strobeBegin,:strobeEnd,:rank,:bankGroup,:bank,"
":row,:column,:burstLength,:transaction)";
"INSERT INTO Phases "
"(PhaseName,PhaseBegin,PhaseEnd,DataStrobeBegin,DataStrobeEnd,Rank,BankGroup,Bank,"
"Row,Column,BurstLength,Transact) VALUES "
"(:name,:begin,:end,:strobeBegin,:strobeEnd,:rank,:bankGroup,:bank,"
":row,:column,:burstLength,:transaction)";
updatePhaseString =
"UPDATE Phases SET PhaseEnd = :end WHERE Transact = :trans AND PhaseName = :name";
"UPDATE Phases SET PhaseEnd = :end WHERE Transact = :trans AND PhaseName = :name";
insertGeneralInfoString =
"INSERT INTO GeneralInfo VALUES"
"(:numberOfRanks, :numberOfBankGroups, :numberOfBanks, :clk, :unitOfTime, "
":mcconfig, :memspec, :traces, :windowSize, :refreshMaxPostponed, :refreshMaxPulledin, :controllerThread, "
":mcconfig, :memspec, :traces, :windowSize, :refreshMaxPostponed, :refreshMaxPulledin, "
":controllerThread, "
":maxBufferDepth, :per2BankOffset, :rowColumnCommandBus, :pseudoChannelMode)";
insertCommandLengthsString = "INSERT INTO CommandLengths VALUES"
"(:command, :length)";
insertDebugMessageString =
"INSERT INTO DebugMessages (Time,Message) Values (:time,:message)";
insertDebugMessageString = "INSERT INTO DebugMessages (Time,Message) Values (:time,:message)";
insertPowerString = "INSERT INTO Power VALUES (:time,:averagePower)";
insertBufferDepthString = "INSERT INTO BufferDepth VALUES (:time,:bufferNumber,:averageBufferDepth)";
insertBufferDepthString =
"INSERT INTO BufferDepth VALUES (:time,:bufferNumber,:averageBufferDepth)";
insertBandwidthString = "INSERT INTO Bandwidth VALUES (:time,:averageBandwidth)";
sqlite3_prepare_v2(db, insertTransactionString.c_str(), -1, &insertTransactionStatement, nullptr);
sqlite3_prepare_v2(
db, insertTransactionString.c_str(), -1, &insertTransactionStatement, nullptr);
sqlite3_prepare_v2(db, insertRangeString.c_str(), -1, &insertRangeStatement, nullptr);
sqlite3_prepare_v2(db, updateRangeString.c_str(), -1, &updateRangeStatement, nullptr);
sqlite3_prepare_v2(db, insertPhaseString.c_str(), -1, &insertPhaseStatement, nullptr);
sqlite3_prepare_v2(db, updatePhaseString.c_str(), -1, &updatePhaseStatement, nullptr);
sqlite3_prepare_v2(db, insertGeneralInfoString.c_str(), -1, &insertGeneralInfoStatement, nullptr);
sqlite3_prepare_v2(db, insertCommandLengthsString.c_str(), -1, &insertCommandLengthsStatement, nullptr);
sqlite3_prepare_v2(db, insertDebugMessageString.c_str(), -1, &insertDebugMessageStatement, nullptr);
sqlite3_prepare_v2(
db, insertGeneralInfoString.c_str(), -1, &insertGeneralInfoStatement, nullptr);
sqlite3_prepare_v2(
db, insertCommandLengthsString.c_str(), -1, &insertCommandLengthsStatement, nullptr);
sqlite3_prepare_v2(
db, insertDebugMessageString.c_str(), -1, &insertDebugMessageStatement, nullptr);
sqlite3_prepare_v2(db, insertPowerString.c_str(), -1, &insertPowerStatement, nullptr);
sqlite3_prepare_v2(db, insertBufferDepthString.c_str(), -1, &insertBufferDepthStatement, nullptr);
sqlite3_prepare_v2(
db, insertBufferDepthString.c_str(), -1, &insertBufferDepthStatement, nullptr);
sqlite3_prepare_v2(db, insertBandwidthString.c_str(), -1, &insertBandwidthStatement, nullptr);
}
void TlmRecorder::insertDebugMessageInDB(const std::string &message, const sc_time &time)
void TlmRecorder::insertDebugMessageInDB(const std::string& message, const sc_time& time)
{
sqlite3_bind_int64(insertDebugMessageStatement, 1, static_cast<int64_t>(time.value()));
sqlite3_bind_text(insertDebugMessageStatement, 2, message.c_str(), static_cast<int>(message.length()), nullptr);
sqlite3_bind_text(insertDebugMessageStatement,
2,
message.c_str(),
static_cast<int>(message.length()),
nullptr);
executeSqlStatement(insertDebugMessageStatement);
}
void TlmRecorder::insertGeneralInfo()
{
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>(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_text(insertGeneralInfoStatement, 5, "PS", 2, nullptr);
sqlite3_bind_text(insertGeneralInfoStatement, 6, mcconfig.c_str(), static_cast<int>(mcconfig.length()), nullptr);
sqlite3_bind_text(insertGeneralInfoStatement, 7, memspec.c_str(), static_cast<int>(memspec.length()), nullptr);
sqlite3_bind_text(insertGeneralInfoStatement, 8, traces.c_str(), static_cast<int>(traces.length()), nullptr);
sqlite3_bind_text(insertGeneralInfoStatement,
6,
mcconfig.c_str(),
static_cast<int>(mcconfig.length()),
nullptr);
sqlite3_bind_text(insertGeneralInfoStatement,
7,
memspec.c_str(),
static_cast<int>(memspec.length()),
nullptr);
sqlite3_bind_text(
insertGeneralInfoStatement, 8, traces.c_str(), static_cast<int>(traces.length()), nullptr);
if (config.enableWindowing)
sqlite3_bind_int64(insertGeneralInfoStatement, 9, static_cast<int64_t>((config.memSpec->tCK
* config.windowSize).value()));
sqlite3_bind_int64(insertGeneralInfoStatement,
9,
static_cast<int64_t>((config.memSpec->tCK * config.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()));
sqlite3_bind_int(
insertGeneralInfoStatement, 14, static_cast<int>(config.memSpec->getPer2BankOffset()));
const MemSpec& memSpec = *config.memSpec;
const auto memoryType = memSpec.memoryType;
bool rowColumnCommandBus = (memoryType == MemSpec::MemoryType::HBM2) || (memoryType == MemSpec::MemoryType::HBM3);
bool rowColumnCommandBus =
(memoryType == MemSpec::MemoryType::HBM2) || (memoryType == MemSpec::MemoryType::HBM3);
bool pseudoChannelMode = [&memSpec, memoryType]() -> bool {
bool pseudoChannelMode = [&memSpec, memoryType]() -> bool
{
if (memoryType != MemSpec::MemoryType::HBM2 && memoryType != MemSpec::MemoryType::HBM3)
return false;
@@ -435,11 +492,14 @@ void TlmRecorder::insertCommandLengths()
{
const MemSpec& _memSpec = *config.memSpec;
auto insertCommandLength = [this, &_memSpec](Command command) {
auto insertCommandLength = [this, &_memSpec](Command command)
{
auto commandName = command.toString();
sqlite3_bind_text(insertCommandLengthsStatement, 1, commandName.c_str(), commandName.length(), nullptr);
sqlite3_bind_double(insertCommandLengthsStatement, 2, _memSpec.getCommandLengthInCycles(command));
sqlite3_bind_text(
insertCommandLengthsStatement, 1, commandName.c_str(), commandName.length(), nullptr);
sqlite3_bind_double(
insertCommandLengthsStatement, 2, _memSpec.getCommandLengthInCycles(command));
executeSqlStatement(insertCommandLengthsStatement);
};
@@ -447,26 +507,23 @@ void TlmRecorder::insertCommandLengths()
insertCommandLength(static_cast<Command::Type>(command));
}
void TlmRecorder::insertTransactionInDB(const Transaction &recordingData)
void TlmRecorder::insertTransactionInDB(const Transaction& recordingData)
{
sqlite3_bind_int(insertTransactionStatement, 1, static_cast<int>(recordingData.id));
sqlite3_bind_int(insertTransactionStatement, 2, static_cast<int>(recordingData.id));
sqlite3_bind_int64(insertTransactionStatement, 3, static_cast<int64_t>(recordingData.address));
sqlite3_bind_int(insertTransactionStatement, 4, static_cast<int>(recordingData.dataLength));
sqlite3_bind_int(insertTransactionStatement, 5,
static_cast<int>(recordingData.thread));
sqlite3_bind_int(insertTransactionStatement, 6,
static_cast<int>(recordingData.channel));
sqlite3_bind_int64(insertTransactionStatement, 7,
sqlite3_bind_int(insertTransactionStatement, 5, static_cast<int>(recordingData.thread));
sqlite3_bind_int(insertTransactionStatement, 6, static_cast<int>(recordingData.channel));
sqlite3_bind_int64(insertTransactionStatement,
7,
static_cast<int64_t>(recordingData.timeOfGeneration.value()));
sqlite3_bind_text(insertTransactionStatement, 8,
&recordingData.cmd, 1, nullptr);
sqlite3_bind_text(insertTransactionStatement, 8, &recordingData.cmd, 1, nullptr);
executeSqlStatement(insertTransactionStatement);
}
void TlmRecorder::insertRangeInDB(uint64_t id, const sc_time &begin,
const sc_time &end)
void TlmRecorder::insertRangeInDB(uint64_t id, const sc_time& begin, const sc_time& end)
{
sqlite3_bind_int64(insertRangeStatement, 1, static_cast<int64_t>(id));
sqlite3_bind_int64(insertRangeStatement, 2, static_cast<int64_t>(begin.value()));
@@ -476,11 +533,17 @@ void TlmRecorder::insertRangeInDB(uint64_t id, const sc_time &begin,
void TlmRecorder::insertPhaseInDB(const Transaction::Phase& phase, uint64_t transactionID)
{
sqlite3_bind_text(insertPhaseStatement, 1, phase.name.c_str(), static_cast<int>(phase.name.length()), nullptr);
sqlite3_bind_text(insertPhaseStatement,
1,
phase.name.c_str(),
static_cast<int>(phase.name.length()),
nullptr);
sqlite3_bind_int64(insertPhaseStatement, 2, static_cast<int64_t>(phase.interval.start.value()));
sqlite3_bind_int64(insertPhaseStatement, 3, static_cast<int64_t>(phase.interval.end.value()));
sqlite3_bind_int64(insertPhaseStatement, 4, static_cast<int64_t>(phase.intervalOnDataStrobe.start.value()));
sqlite3_bind_int64(insertPhaseStatement, 5, static_cast<int64_t>(phase.intervalOnDataStrobe.end.value()));
sqlite3_bind_int64(
insertPhaseStatement, 4, static_cast<int64_t>(phase.intervalOnDataStrobe.start.value()));
sqlite3_bind_int64(
insertPhaseStatement, 5, static_cast<int64_t>(phase.intervalOnDataStrobe.end.value()));
sqlite3_bind_int(insertPhaseStatement, 6, static_cast<int>(phase.rank));
sqlite3_bind_int(insertPhaseStatement, 7, static_cast<int>(phase.bankGroup));
sqlite3_bind_int(insertPhaseStatement, 8, static_cast<int>(phase.bank));
@@ -491,13 +554,14 @@ void TlmRecorder::insertPhaseInDB(const Transaction::Phase& phase, uint64_t tran
executeSqlStatement(insertPhaseStatement);
}
void TlmRecorder::executeSqlStatement(sqlite3_stmt *statement)
void TlmRecorder::executeSqlStatement(sqlite3_stmt* statement)
{
int errorCode = sqlite3_step(statement);
if (errorCode != SQLITE_DONE)
SC_REPORT_FATAL("Error in TraceRecorder",
(std::string("Could not execute statement. Error code: ") + std::to_string(errorCode)).c_str());
SC_REPORT_FATAL(
"Error in TraceRecorder",
(std::string("Could not execute statement. Error code: ") + std::to_string(errorCode))
.c_str());
sqlite3_reset(statement);
}
@@ -506,9 +570,10 @@ void TlmRecorder::executeInitialSqlCommand()
{
PRINTDEBUGMESSAGE(name, "Creating database by running provided sql script");
char *errMsg = nullptr;
char* errMsg = nullptr;
int rc = sqlite3_exec(db, initialCommand.c_str(), nullptr, nullptr, &errMsg);
if (rc != SQLITE_OK) {
if (rc != SQLITE_OK)
{
SC_REPORT_FATAL("SQLITE Error", errMsg);
sqlite3_free(errMsg);
}
@@ -523,8 +588,8 @@ void TlmRecorder::closeConnection()
storageThread.join();
std::swap(currentDataBuffer, storageDataBuffer);
commitRecordedDataToDB();
PRINTDEBUGMESSAGE(name, "Number of transactions written to DB: "
+ std::to_string(totalNumTransactions));
PRINTDEBUGMESSAGE(
name, "Number of transactions written to DB: " + std::to_string(totalNumTransactions));
PRINTDEBUGMESSAGE(name, "tlmPhaseRecorder:\tEnd Recording");
sqlite3_close(db);
db = nullptr;

View File

@@ -41,9 +41,9 @@
#ifndef TLMRECORDER_H
#define TLMRECORDER_H
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/common/dramExtensions.h"
#include "DRAMSys/common/utils.h"
#include "DRAMSys/configuration/Configuration.h"
#include <string>
#include <systemc>
@@ -63,32 +63,25 @@ class TlmRecorder
{
public:
TlmRecorder(const std::string& name, const Configuration& config, const std::string& dbName);
TlmRecorder(const TlmRecorder &) = delete;
TlmRecorder(TlmRecorder &&) = default;
TlmRecorder &operator=(const TlmRecorder &) = delete;
TlmRecorder &operator=(TlmRecorder &&) = delete;
TlmRecorder(const TlmRecorder&) = delete;
TlmRecorder(TlmRecorder&&) = default;
TlmRecorder& operator=(const TlmRecorder&) = delete;
TlmRecorder& operator=(TlmRecorder&&) = delete;
~TlmRecorder() = default;
void recordMcConfig(std::string _mcconfig)
{
mcconfig = std::move(_mcconfig);
}
void recordMcConfig(std::string _mcconfig) { mcconfig = std::move(_mcconfig); }
void recordMemspec(std::string _memspec)
{
memspec = std::move(_memspec);
}
void recordMemspec(std::string _memspec) { memspec = std::move(_memspec); }
void recordTraceNames(std::string _traces)
{
traces = std::move(_traces);
}
void recordTraceNames(std::string _traces) { traces = std::move(_traces); }
void recordPhase(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase, const sc_core::sc_time& delay);
void recordPhase(tlm::tlm_generic_payload& trans,
const tlm::tlm_phase& phase,
const sc_core::sc_time& delay);
void recordPower(double timeInSeconds, double averagePower);
void recordBufferDepth(double timeInSeconds, const std::vector<double> &averageBufferDepth);
void recordBufferDepth(double timeInSeconds, const std::vector<double>& averageBufferDepth);
void recordBandwidth(double timeInSeconds, double averageBandwidth);
void recordDebugMessage(const std::string &message, const sc_core::sc_time &time);
void recordDebugMessage(const std::string& message, const sc_core::sc_time& time);
void finalize();
private:
@@ -98,10 +91,22 @@ private:
struct Transaction
{
Transaction(uint64_t id, uint64_t address, unsigned int dataLength, char cmd,
const sc_core::sc_time& timeOfGeneration, Thread thread, Channel channel) :
id(id), address(address), dataLength(dataLength), cmd(cmd), timeOfGeneration(timeOfGeneration),
thread(thread), channel(channel) {}
Transaction(uint64_t id,
uint64_t address,
unsigned int dataLength,
char cmd,
const sc_core::sc_time& timeOfGeneration,
Thread thread,
Channel channel) :
id(id),
address(address),
dataLength(dataLength),
cmd(cmd),
timeOfGeneration(timeOfGeneration),
thread(thread),
channel(channel)
{
}
uint64_t id = 0;
uint64_t address = 0;
@@ -114,13 +119,31 @@ private:
struct Phase
{
// for BEGIN_REQ and BEGIN_RESP
Phase(std::string name, const sc_core::sc_time& begin) : name(std::move(name)),
interval(begin, sc_core::SC_ZERO_TIME) {}
Phase(std::string name, TimeInterval interval, TimeInterval intervalOnDataStrobe, Rank rank,
BankGroup bankGroup, Bank bank, Row row, Column column, unsigned int burstLength) :
name(std::move(name)), interval(std::move(interval)),
intervalOnDataStrobe(std::move(intervalOnDataStrobe)), rank(rank), bankGroup(bankGroup), bank(bank),
row(row), column(column), burstLength(burstLength) {}
Phase(std::string name, const sc_core::sc_time& begin) :
name(std::move(name)),
interval(begin, sc_core::SC_ZERO_TIME)
{
}
Phase(std::string name,
TimeInterval interval,
TimeInterval intervalOnDataStrobe,
Rank rank,
BankGroup bankGroup,
Bank bank,
Row row,
Column column,
unsigned int burstLength) :
name(std::move(name)),
interval(std::move(interval)),
intervalOnDataStrobe(std::move(intervalOnDataStrobe)),
rank(rank),
bankGroup(bankGroup),
bank(bank),
row(row),
column(column),
burstLength(burstLength)
{
}
std::string name;
TimeInterval interval;
TimeInterval intervalOnDataStrobe = {sc_core::SC_ZERO_TIME, sc_core::SC_ZERO_TIME};
@@ -138,27 +161,27 @@ private:
void prepareSqlStatements();
void executeInitialSqlCommand();
static void executeSqlStatement(sqlite3_stmt *statement);
static void executeSqlStatement(sqlite3_stmt* statement);
void openDB(const std::string &dbName);
void openDB(const std::string& dbName);
void closeConnection();
void introduceTransactionToSystem(tlm::tlm_generic_payload &trans);
void removeTransactionFromSystem(tlm::tlm_generic_payload &trans);
void introduceTransactionToSystem(tlm::tlm_generic_payload& trans);
void removeTransactionFromSystem(tlm::tlm_generic_payload& trans);
void terminateRemainingTransactions();
void commitRecordedDataToDB();
void insertGeneralInfo();
void insertCommandLengths();
void insertTransactionInDB(const Transaction& recordingData);
void insertRangeInDB(uint64_t id, const sc_core::sc_time &begin, const sc_core::sc_time &end);
void insertRangeInDB(uint64_t id, const sc_core::sc_time& begin, const sc_core::sc_time& end);
void insertPhaseInDB(const Transaction::Phase& phase, uint64_t transactionID);
void insertDebugMessageInDB(const std::string &message, const sc_core::sc_time &time);
void insertDebugMessageInDB(const std::string& message, const sc_core::sc_time& time);
static constexpr unsigned transactionCommitRate = 8192;
std::array<std::vector<Transaction>, 2> recordingDataBuffer;
std::vector<Transaction> *currentDataBuffer;
std::vector<Transaction> *storageDataBuffer;
std::vector<Transaction>* currentDataBuffer;
std::vector<Transaction>* storageDataBuffer;
std::thread storageThread;
std::unordered_map<tlm::tlm_generic_payload*, Transaction> currentTransactionsInSystem;
@@ -166,16 +189,16 @@ private:
uint64_t totalNumTransactions = 0;
sc_core::sc_time simulationTimeCoveredByRecording;
sqlite3 *db = nullptr;
sqlite3* db = nullptr;
sqlite3_stmt *insertTransactionStatement = nullptr, *insertRangeStatement = nullptr,
*updateRangeStatement = nullptr, *insertPhaseStatement = nullptr, *updatePhaseStatement = nullptr,
*insertGeneralInfoStatement = nullptr, *insertCommandLengthsStatement = nullptr,
*insertDebugMessageStatement = nullptr, *insertPowerStatement = nullptr,
*insertBufferDepthStatement = nullptr, *insertBandwidthStatement = nullptr;
*updateRangeStatement = nullptr, *insertPhaseStatement = nullptr,
*updatePhaseStatement = nullptr, *insertGeneralInfoStatement = nullptr,
*insertCommandLengthsStatement = nullptr, *insertDebugMessageStatement = nullptr,
*insertPowerStatement = nullptr, *insertBufferDepthStatement = nullptr,
*insertBandwidthStatement = nullptr;
std::string insertTransactionString, insertRangeString, updateRangeString, insertPhaseString,
updatePhaseString, insertGeneralInfoString, insertCommandLengthsString,
insertDebugMessageString, insertPowerString,
insertBufferDepthString, insertBandwidthString;
updatePhaseString, insertGeneralInfoString, insertCommandLengthsString,
insertDebugMessageString, insertPowerString, insertBufferDepthString, insertBandwidthString;
std::string initialCommand = R"(
DROP TABLE IF EXISTS Phases;

View File

@@ -44,12 +44,20 @@ using namespace tlm;
namespace DRAMSys
{
ArbiterExtension::ArbiterExtension(Thread thread, Channel channel, uint64_t threadPayloadID,
ArbiterExtension::ArbiterExtension(Thread thread,
Channel channel,
uint64_t threadPayloadID,
const sc_core::sc_time& timeOfGeneration) :
thread(thread), channel(channel), threadPayloadID(threadPayloadID), timeOfGeneration(timeOfGeneration)
{}
thread(thread),
channel(channel),
threadPayloadID(threadPayloadID),
timeOfGeneration(timeOfGeneration)
{
}
void ArbiterExtension::setAutoExtension(tlm::tlm_generic_payload& trans, Thread thread, Channel channel)
void ArbiterExtension::setAutoExtension(tlm::tlm_generic_payload& trans,
Thread thread,
Channel channel)
{
auto* extension = trans.get_extension<ArbiterExtension>();
@@ -67,15 +75,19 @@ void ArbiterExtension::setAutoExtension(tlm::tlm_generic_payload& trans, Thread
}
}
void ArbiterExtension::setExtension(tlm::tlm_generic_payload& trans, Thread thread, Channel channel,
uint64_t threadPayloadID, const sc_core::sc_time& timeOfGeneration)
void ArbiterExtension::setExtension(tlm::tlm_generic_payload& trans,
Thread thread,
Channel channel,
uint64_t threadPayloadID,
const sc_core::sc_time& timeOfGeneration)
{
assert(trans.get_extension<ArbiterExtension>() == nullptr);
auto* extension = new ArbiterExtension(thread, channel, threadPayloadID, timeOfGeneration);
trans.set_extension(extension);
}
void ArbiterExtension::setIDAndTimeOfGeneration(tlm::tlm_generic_payload& trans, uint64_t threadPayloadID,
void ArbiterExtension::setIDAndTimeOfGeneration(tlm::tlm_generic_payload& trans,
uint64_t threadPayloadID,
const sc_core::sc_time& timeOfGeneration)
{
assert(trans.get_extension<ArbiterExtension>() != nullptr);
@@ -144,14 +156,31 @@ sc_time ArbiterExtension::getTimeOfGeneration(const tlm::tlm_generic_payload& tr
return trans.get_extension<ArbiterExtension>()->timeOfGeneration;
}
ControllerExtension::ControllerExtension(uint64_t channelPayloadID, Rank rank, BankGroup bankGroup, Bank bank, Row row,
Column column, unsigned int burstLength) :
channelPayloadID(channelPayloadID), rank(rank), bankGroup(bankGroup), bank(bank), row(row), column(column),
burstLength(burstLength)
{}
ControllerExtension::ControllerExtension(uint64_t channelPayloadID,
Rank rank,
BankGroup bankGroup,
Bank bank,
Row row,
Column column,
unsigned int burstLength) :
channelPayloadID(channelPayloadID),
rank(rank),
bankGroup(bankGroup),
bank(bank),
row(row),
column(column),
burstLength(burstLength)
{
}
void ControllerExtension::setAutoExtension(tlm::tlm_generic_payload& trans, uint64_t channelPayloadID, Rank rank,
BankGroup bankGroup, Bank bank, Row row, Column column, unsigned int burstLength)
void ControllerExtension::setAutoExtension(tlm::tlm_generic_payload& trans,
uint64_t channelPayloadID,
Rank rank,
BankGroup bankGroup,
Bank bank,
Row row,
Column column,
unsigned int burstLength)
{
auto* extension = trans.get_extension<ControllerExtension>();
@@ -167,22 +196,31 @@ void ControllerExtension::setAutoExtension(tlm::tlm_generic_payload& trans, uint
}
else
{
extension = new ControllerExtension(channelPayloadID, rank, bankGroup, bank, row, column, burstLength);
extension = new ControllerExtension(
channelPayloadID, rank, bankGroup, bank, row, column, burstLength);
trans.set_auto_extension(extension);
}
}
void ControllerExtension::setExtension(tlm::tlm_generic_payload& trans, uint64_t channelPayloadID, Rank rank,
BankGroup bankGroup, Bank bank, Row row, Column column, unsigned int burstLength)
void ControllerExtension::setExtension(tlm::tlm_generic_payload& trans,
uint64_t channelPayloadID,
Rank rank,
BankGroup bankGroup,
Bank bank,
Row row,
Column column,
unsigned int burstLength)
{
assert(trans.get_extension<ControllerExtension>() == nullptr);
auto* extension = new ControllerExtension(channelPayloadID, rank, bankGroup, bank, row, column, burstLength);
auto* extension =
new ControllerExtension(channelPayloadID, rank, bankGroup, bank, row, column, burstLength);
trans.set_extension(extension);
}
tlm_extension_base* ControllerExtension::clone() const
{
return new ControllerExtension(channelPayloadID, rank, bankGroup, bank, row, column, burstLength);
return new ControllerExtension(
channelPayloadID, rank, bankGroup, bank, row, column, burstLength);
}
void ControllerExtension::copy_from(const tlm_extension_base& ext)
@@ -293,7 +331,8 @@ tlm::tlm_generic_payload& ChildExtension::getParentTrans(tlm::tlm_generic_payloa
return childTrans.get_extension<ChildExtension>()->getParentTrans();
}
void ChildExtension::setExtension(tlm::tlm_generic_payload& childTrans, tlm::tlm_generic_payload& parentTrans)
void ChildExtension::setExtension(tlm::tlm_generic_payload& childTrans,
tlm::tlm_generic_payload& parentTrans)
{
auto* extension = childTrans.get_extension<ChildExtension>();
@@ -324,7 +363,8 @@ void ParentExtension::copy_from(const tlm_extension_base& ext)
childTranses = cpyFrom.childTranses;
}
void ParentExtension::setExtension(tlm::tlm_generic_payload& parentTrans, std::vector<tlm::tlm_generic_payload*> childTranses)
void ParentExtension::setExtension(tlm::tlm_generic_payload& parentTrans,
std::vector<tlm::tlm_generic_payload*> childTranses)
{
auto* extension = parentTrans.get_extension<ParentExtension>();
@@ -350,8 +390,9 @@ bool ParentExtension::notifyChildTransCompletion()
completedChildTranses++;
if (completedChildTranses == childTranses.size())
{
std::for_each(childTranses.begin(), childTranses.end(),
[](tlm::tlm_generic_payload* childTrans){childTrans->release();});
std::for_each(childTranses.begin(),
childTranses.end(),
[](tlm::tlm_generic_payload* childTrans) { childTrans->release(); });
childTranses.clear();
return true;
}

View File

@@ -57,7 +57,7 @@ enum class Bank : std::size_t;
enum class Row : std::size_t;
enum class Column : std::size_t;
template<typename IndexType, typename ValueType>
template <typename IndexType, typename ValueType>
class ControllerVector : private std::vector<ValueType>
{
public:
@@ -82,9 +82,13 @@ class ArbiterExtension : public tlm::tlm_extension<ArbiterExtension>
{
public:
static void setAutoExtension(tlm::tlm_generic_payload& trans, Thread thread, Channel channel);
static void setExtension(tlm::tlm_generic_payload& trans, Thread thread, Channel channel,
uint64_t threadPayloadID, const sc_core::sc_time& timeOfGeneration);
static void setIDAndTimeOfGeneration(tlm::tlm_generic_payload& trans, uint64_t threadPayloadID,
static void setExtension(tlm::tlm_generic_payload& trans,
Thread thread,
Channel channel,
uint64_t threadPayloadID,
const sc_core::sc_time& timeOfGeneration);
static void setIDAndTimeOfGeneration(tlm::tlm_generic_payload& trans,
uint64_t threadPayloadID,
const sc_core::sc_time& timeOfGeneration);
[[nodiscard]] tlm::tlm_extension_base* clone() const override;
@@ -102,7 +106,10 @@ public:
static sc_core::sc_time getTimeOfGeneration(const tlm::tlm_generic_payload& trans);
private:
ArbiterExtension(Thread thread, Channel channel, uint64_t threadPayloadID, const sc_core::sc_time& timeOfGeneration);
ArbiterExtension(Thread thread,
Channel channel,
uint64_t threadPayloadID,
const sc_core::sc_time& timeOfGeneration);
Thread thread;
Channel channel;
uint64_t threadPayloadID;
@@ -112,13 +119,25 @@ private:
class ControllerExtension : public tlm::tlm_extension<ControllerExtension>
{
public:
static void setAutoExtension(tlm::tlm_generic_payload& trans, uint64_t channelPayloadID, Rank rank, BankGroup bankGroup,
Bank bank, Row row, Column column, unsigned burstLength);
static void setAutoExtension(tlm::tlm_generic_payload& trans,
uint64_t channelPayloadID,
Rank rank,
BankGroup bankGroup,
Bank bank,
Row row,
Column column,
unsigned burstLength);
static void setExtension(tlm::tlm_generic_payload& trans, uint64_t channelPayloadID, Rank rank, BankGroup bankGroup,
Bank bank, Row row, Column column, unsigned burstLength);
static void setExtension(tlm::tlm_generic_payload& trans,
uint64_t channelPayloadID,
Rank rank,
BankGroup bankGroup,
Bank bank,
Row row,
Column column,
unsigned burstLength);
//static ControllerExtension& getExtension(const tlm::tlm_generic_payload& trans);
// static ControllerExtension& getExtension(const tlm::tlm_generic_payload& trans);
[[nodiscard]] tlm::tlm_extension_base* clone() const override;
void copy_from(const tlm::tlm_extension_base& ext) override;
@@ -141,7 +160,12 @@ public:
static unsigned getBurstLength(const tlm::tlm_generic_payload& trans);
private:
ControllerExtension(uint64_t channelPayloadID, Rank rank, BankGroup bankGroup, Bank bank, Row row, Column column,
ControllerExtension(uint64_t channelPayloadID,
Rank rank,
BankGroup bankGroup,
Bank bank,
Row row,
Column column,
unsigned burstLength);
uint64_t channelPayloadID;
Rank rank;
@@ -159,13 +183,14 @@ private:
explicit ChildExtension(tlm::tlm_generic_payload& parentTrans) : parentTrans(&parentTrans) {}
public:
//ChildExtension() = delete;
// ChildExtension() = delete;
[[nodiscard]] tlm::tlm_extension_base* clone() const override;
void copy_from(const tlm::tlm_extension_base& ext) override;
tlm::tlm_generic_payload& getParentTrans();
static tlm::tlm_generic_payload& getParentTrans(tlm::tlm_generic_payload& childTrans);
static void setExtension(tlm::tlm_generic_payload& childTrans, tlm::tlm_generic_payload& parentTrans);
static void setExtension(tlm::tlm_generic_payload& childTrans,
tlm::tlm_generic_payload& parentTrans);
static bool isChildTrans(const tlm::tlm_generic_payload& trans);
};
@@ -174,15 +199,18 @@ class ParentExtension : public tlm::tlm_extension<ParentExtension>
private:
std::vector<tlm::tlm_generic_payload*> childTranses;
unsigned completedChildTranses = 0;
explicit ParentExtension(std::vector<tlm::tlm_generic_payload*> _childTranses)
: childTranses(std::move(_childTranses)) {}
explicit ParentExtension(std::vector<tlm::tlm_generic_payload*> _childTranses) :
childTranses(std::move(_childTranses))
{
}
public:
ParentExtension() = delete;
[[nodiscard]] tlm_extension_base* clone() const override;
void copy_from(const tlm_extension_base& ext) override;
static void setExtension(tlm::tlm_generic_payload& parentTrans, std::vector<tlm::tlm_generic_payload*> childTranses);
static void setExtension(tlm::tlm_generic_payload& parentTrans,
std::vector<tlm::tlm_generic_payload*> childTranses);
const std::vector<tlm::tlm_generic_payload*>& getChildTranses();
bool notifyChildTransCompletion();
static bool notifyChildTransCompletion(tlm::tlm_generic_payload& trans);
@@ -191,12 +219,9 @@ public:
class EccExtension : public tlm::tlm_extension<EccExtension>
{
public:
[[nodiscard]] tlm_extension_base* clone() const override
{
return new EccExtension;
}
[[nodiscard]] tlm_extension_base* clone() const override { return new EccExtension; }
void copy_from([[maybe_unused]] tlm_extension_base const & ext) override {}
void copy_from([[maybe_unused]] tlm_extension_base const& ext) override {}
};
} // namespace DRAMSys

View File

@@ -47,33 +47,36 @@ using namespace tlm;
namespace DRAMSys
{
bool TimeInterval::timeIsInInterval(const sc_time &time) const
bool TimeInterval::timeIsInInterval(const sc_time& time) const
{
return (start < time && time < end);
}
bool TimeInterval::intersects(const TimeInterval &other) const
bool TimeInterval::intersects(const TimeInterval& other) const
{
return other.timeIsInInterval(this->start)
|| this->timeIsInInterval(other.start);
return other.timeIsInInterval(this->start) || this->timeIsInInterval(other.start);
}
sc_time TimeInterval::getLength() const
{
if (start > end)
return start - end;
return end - start;
}
std::string getPhaseName(const tlm_phase &phase)
std::string getPhaseName(const tlm_phase& phase)
{
std::ostringstream oss;
oss << phase;
return oss.str();
}
void setUpDummy(tlm_generic_payload &payload, uint64_t channelPayloadID, Rank rank, BankGroup bankGroup, Bank bank)
void setUpDummy(tlm_generic_payload& payload,
uint64_t channelPayloadID,
Rank rank,
BankGroup bankGroup,
Bank bank)
{
payload.set_address(0);
payload.set_command(TLM_IGNORE_COMMAND);
@@ -82,7 +85,8 @@ void setUpDummy(tlm_generic_payload &payload, uint64_t channelPayloadID, Rank ra
payload.set_dmi_allowed(false);
payload.set_byte_enable_length(0);
payload.set_streaming_width(0);
ControllerExtension::setExtension(payload, channelPayloadID, rank, bankGroup, bank, Row(0), Column(0), 0);
ControllerExtension::setExtension(
payload, channelPayloadID, rank, bankGroup, bank, Row(0), Column(0), 0);
ArbiterExtension::setExtension(payload, Thread(UINT_MAX), Channel(0), 0, SC_ZERO_TIME);
}

View File

@@ -42,9 +42,9 @@
#include "DRAMSys/common/dramExtensions.h"
#include <string>
#include <systemc>
#include <tlm>
#include <string>
namespace DRAMSys
{
@@ -54,20 +54,27 @@ class TimeInterval
public:
sc_core::sc_time start, end;
TimeInterval() : start(sc_core::SC_ZERO_TIME), end(sc_core::SC_ZERO_TIME) {}
TimeInterval(const sc_core::sc_time& start, const sc_core::sc_time& end) : start(start), end(end) {}
TimeInterval(const sc_core::sc_time& start, const sc_core::sc_time& end) :
start(start),
end(end)
{
}
[[nodiscard]] sc_core::sc_time getLength() const;
[[nodiscard]] bool timeIsInInterval(const sc_core::sc_time &time) const;
[[nodiscard]] bool intersects(const TimeInterval &other) const;
[[nodiscard]] bool timeIsInInterval(const sc_core::sc_time& time) const;
[[nodiscard]] bool intersects(const TimeInterval& other) const;
};
constexpr const std::string_view headline =
"===========================================================================";
std::string getPhaseName(const tlm::tlm_phase &phase);
std::string getPhaseName(const tlm::tlm_phase& phase);
void setUpDummy(tlm::tlm_generic_payload &payload, uint64_t channelPayloadID,
Rank rank = Rank(0), BankGroup bankGroup = BankGroup(0), Bank bank = Bank(0));
void setUpDummy(tlm::tlm_generic_payload& payload,
uint64_t channelPayloadID,
Rank rank = Rank(0),
BankGroup bankGroup = BankGroup(0),
Bank bank = Bank(0));
bool isFullCycle(sc_core::sc_time time, sc_core::sc_time cycleTime);
sc_core::sc_time alignAtNext(sc_core::sc_time time, sc_core::sc_time alignment);

View File

@@ -43,14 +43,14 @@
#include "DRAMSys/configuration/memspec/MemSpecDDR3.h"
#include "DRAMSys/configuration/memspec/MemSpecDDR4.h"
#include "DRAMSys/configuration/memspec/MemSpecWideIO.h"
#include "DRAMSys/configuration/memspec/MemSpecLPDDR4.h"
#include "DRAMSys/configuration/memspec/MemSpecWideIO2.h"
#include "DRAMSys/configuration/memspec/MemSpecHBM2.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"
@@ -67,7 +67,7 @@ using namespace sc_core;
namespace DRAMSys
{
enum sc_time_unit string2TimeUnit(const std::string &s)
enum sc_time_unit string2TimeUnit(const std::string& s)
{
if (s == "s")
return SC_SEC;
@@ -87,12 +87,11 @@ enum sc_time_unit string2TimeUnit(const std::string &s)
if (s == "fs")
return SC_FS;
SC_REPORT_FATAL("Configuration",
("Could not convert to enum sc_time_unit: " + s).c_str());
SC_REPORT_FATAL("Configuration", ("Could not convert to enum sc_time_unit: " + s).c_str());
throw;
}
void Configuration::loadSimConfig(const DRAMSys::Config::SimConfig &simConfig)
void Configuration::loadSimConfig(const DRAMSys::Config::SimConfig& simConfig)
{
addressOffset = simConfig.AddressOffset.value_or(addressOffset);
checkTLM2Protocol = simConfig.CheckTLM2Protocol.value_or(checkTLM2Protocol);
@@ -103,7 +102,7 @@ void Configuration::loadSimConfig(const DRAMSys::Config::SimConfig &simConfig)
simulationProgressBar = simConfig.SimulationProgressBar.value_or(simulationProgressBar);
useMalloc = simConfig.UseMalloc.value_or(useMalloc);
if (const auto &_storeMode = simConfig.StoreMode)
if (const auto& _storeMode = simConfig.StoreMode)
storeMode = [=]
{
switch (*_storeMode)
@@ -120,18 +119,19 @@ void Configuration::loadSimConfig(const DRAMSys::Config::SimConfig &simConfig)
windowSize = simConfig.WindowSize.value_or(windowSize);
if (windowSize == 0)
SC_REPORT_FATAL("Configuration", "Minimum window size is 1");
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!");
SC_REPORT_FATAL("Configuration",
"Power analysis is only supported with included DRAMPower library!");
#endif
}
void Configuration::loadMCConfig(const DRAMSys::Config::McConfig &mcConfig)
void Configuration::loadMCConfig(const DRAMSys::Config::McConfig& mcConfig)
{
if (const auto &_pagePolicy = mcConfig.PagePolicy)
if (const auto& _pagePolicy = mcConfig.PagePolicy)
pagePolicy = [=]
{
switch (*_pagePolicy)
@@ -150,7 +150,7 @@ void Configuration::loadMCConfig(const DRAMSys::Config::McConfig &mcConfig)
}
}();
if (const auto &_scheduler = mcConfig.Scheduler)
if (const auto& _scheduler = mcConfig.Scheduler)
scheduler = [=]
{
switch (*_scheduler)
@@ -171,7 +171,7 @@ void Configuration::loadMCConfig(const DRAMSys::Config::McConfig &mcConfig)
}
}();
if (const auto &_schedulerBuffer = mcConfig.SchedulerBuffer)
if (const auto& _schedulerBuffer = mcConfig.SchedulerBuffer)
schedulerBuffer = [=]
{
switch (*_schedulerBuffer)
@@ -188,7 +188,7 @@ void Configuration::loadMCConfig(const DRAMSys::Config::McConfig &mcConfig)
}
}();
if (const auto &_cmdMux = mcConfig.CmdMux)
if (const auto& _cmdMux = mcConfig.CmdMux)
cmdMux = [=]
{
switch (*_cmdMux)
@@ -203,7 +203,7 @@ void Configuration::loadMCConfig(const DRAMSys::Config::McConfig &mcConfig)
}
}();
if (const auto &_respQueue = mcConfig.RespQueue)
if (const auto& _respQueue = mcConfig.RespQueue)
respQueue = [=]
{
switch (*_respQueue)
@@ -218,7 +218,7 @@ void Configuration::loadMCConfig(const DRAMSys::Config::McConfig &mcConfig)
}
}();
if (const auto &_refreshPolicy = mcConfig.RefreshPolicy)
if (const auto& _refreshPolicy = mcConfig.RefreshPolicy)
refreshPolicy = [=]
{
switch (*_refreshPolicy)
@@ -239,7 +239,7 @@ void Configuration::loadMCConfig(const DRAMSys::Config::McConfig &mcConfig)
}
}();
if (const auto &_powerDownPolicy = mcConfig.PowerDownPolicy)
if (const auto& _powerDownPolicy = mcConfig.PowerDownPolicy)
powerDownPolicy = [=]
{
switch (*_powerDownPolicy)
@@ -254,7 +254,7 @@ void Configuration::loadMCConfig(const DRAMSys::Config::McConfig &mcConfig)
}
}();
if (const auto &_arbiter = mcConfig.Arbiter)
if (const auto& _arbiter = mcConfig.Arbiter)
arbiter = [=]
{
switch (*_arbiter)
@@ -284,46 +284,50 @@ void Configuration::loadMCConfig(const DRAMSys::Config::McConfig &mcConfig)
if (const auto& _arbitrationDelayFw = mcConfig.ArbitrationDelayFw)
{
arbitrationDelayFw = std::round(sc_time(*_arbitrationDelayFw, SC_NS) / memSpec->tCK) * memSpec->tCK;
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;
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;
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;
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;
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;
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;
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;
blockingWriteDelay =
std::round(sc_time(_blockingWriteDelay, SC_NS) / memSpec->tCK) * memSpec->tCK;
}
}
void Configuration::loadMemSpec(const DRAMSys::Config::MemSpec &memSpecConfig)
void Configuration::loadMemSpec(const DRAMSys::Config::MemSpec& memSpecConfig)
{
std::string memoryType = memSpecConfig.memoryType;

View File

@@ -43,11 +43,11 @@
#ifndef CONFIGURATION_H
#define CONFIGURATION_H
#include "DRAMSys/configuration/memspec/MemSpec.h"
#include "DRAMSys/config/DRAMSysConfiguration.h"
#include "DRAMSys/configuration/memspec/MemSpec.h"
#include <systemc>
#include <string>
#include <systemc>
namespace DRAMSys
{
@@ -56,19 +56,61 @@ 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;
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;
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;
enum class RefreshPolicy {NoRefresh, PerBank, Per2Bank, SameBank, AllBank} refreshPolicy = RefreshPolicy::AllBank;
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;
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;
@@ -92,7 +134,11 @@ public:
bool useMalloc = false;
unsigned long long int addressOffset = 0;
enum class StoreMode {NoStorage, Store} storeMode = StoreMode::NoStorage;
enum class StoreMode
{
NoStorage,
Store
} storeMode = StoreMode::NoStorage;
// MemSpec (from DRAM-Power)
std::unique_ptr<const MemSpec> memSpec;

View File

@@ -1,38 +1,38 @@
/*
* 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:
* Lukas Steiner
* Derek Christ
*/
* 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:
* Lukas Steiner
* Derek Christ
*/
#include "MemSpec.h"
@@ -43,13 +43,17 @@ namespace DRAMSys
{
MemSpec::MemSpec(const DRAMSys::Config::MemSpec& memSpec,
MemoryType memoryType,
unsigned numberOfChannels, unsigned pseudoChannelsPerChannel,
unsigned ranksPerChannel, unsigned banksPerRank,
unsigned groupsPerRank, unsigned banksPerGroup,
unsigned banksPerChannel, unsigned bankGroupsPerChannel,
unsigned devicesPerRank)
: numberOfChannels(numberOfChannels),
MemoryType memoryType,
unsigned numberOfChannels,
unsigned pseudoChannelsPerChannel,
unsigned ranksPerChannel,
unsigned banksPerRank,
unsigned groupsPerRank,
unsigned banksPerGroup,
unsigned banksPerChannel,
unsigned bankGroupsPerChannel,
unsigned devicesPerRank) :
numberOfChannels(numberOfChannels),
pseudoChannelsPerChannel(pseudoChannelsPerChannel),
ranksPerChannel(ranksPerChannel),
banksPerRank(banksPerRank),
@@ -62,21 +66,21 @@ MemSpec::MemSpec(const DRAMSys::Config::MemSpec& memSpec,
columnsPerRow(memSpec.memarchitecturespec.entries.at("nbrOfColumns")),
defaultBurstLength(memSpec.memarchitecturespec.entries.at("burstLength")),
maxBurstLength(memSpec.memarchitecturespec.entries.find("maxBurstLength") !=
memSpec.memarchitecturespec.entries.end()
? memSpec.memarchitecturespec.entries.at("maxBurstLength")
: defaultBurstLength),
memSpec.memarchitecturespec.entries.end()
? memSpec.memarchitecturespec.entries.at("maxBurstLength")
: defaultBurstLength),
dataRate(memSpec.memarchitecturespec.entries.at("dataRate")),
bitWidth(memSpec.memarchitecturespec.entries.at("width")),
dataBusWidth(bitWidth* devicesPerRank),
dataBusWidth(bitWidth * devicesPerRank),
bytesPerBeat(dataBusWidth / 8),
defaultBytesPerBurst((defaultBurstLength* dataBusWidth) / 8),
maxBytesPerBurst((maxBurstLength* dataBusWidth) / 8),
defaultBytesPerBurst((defaultBurstLength * dataBusWidth) / 8),
maxBytesPerBurst((maxBurstLength * dataBusWidth) / 8),
fCKMHz(memSpec.memtimingspec.entries.at("clkMhz")),
tCK(sc_time(1.0 / fCKMHz, SC_US)),
memoryId(memSpec.memoryId),
memoryType(memoryType),
burstDuration(tCK* (static_cast<double>(defaultBurstLength) / dataRate))
burstDuration(tCK * (static_cast<double>(defaultBurstLength) / dataRate))
{
commandLengthInCycles = std::vector<double>(Command::numberOfCommands(), 1);
}

View File

@@ -1,52 +1,52 @@
/*
* 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
* Lukas Steiner
* Derek Christ
*/
* 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
* Lukas Steiner
* Derek Christ
*/
#ifndef MEMSPEC_H
#define MEMSPEC_H
#include "DRAMSys/config/DRAMSysConfiguration.h"
#include "DRAMSys/common/utils.h"
#include "DRAMSys/config/DRAMSysConfiguration.h"
#include "DRAMSys/controller/Command.h"
#include <string>
#include <systemc>
#include <tlm>
#include <vector>
#include <string>
namespace DRAMSys
{
@@ -54,8 +54,8 @@ namespace DRAMSys
class MemSpec
{
public:
MemSpec &operator=(const MemSpec &) = delete;
MemSpec &operator=(MemSpec &&) = delete;
MemSpec& operator=(const MemSpec&) = delete;
MemSpec& operator=(MemSpec&&) = delete;
virtual ~MemSpec() = default;
const unsigned numberOfChannels;
@@ -84,8 +84,19 @@ public:
const std::string memoryId;
const enum class MemoryType {
DDR3, DDR4, DDR5, LPDDR4, LPDDR5, WideIO,
WideIO2, GDDR5, GDDR5X, GDDR6, HBM2, HBM3, STTMRAM
DDR3,
DDR4,
DDR5,
LPDDR4,
LPDDR5,
WideIO,
WideIO2,
GDDR5,
GDDR5X,
GDDR6,
HBM2,
HBM3,
STTMRAM
} memoryType;
[[nodiscard]] virtual sc_core::sc_time getRefreshIntervalAB() const;
@@ -101,8 +112,10 @@ public:
[[nodiscard]] virtual bool hasRasAndCasBus() const;
[[nodiscard]] virtual sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const = 0;
[[nodiscard]] virtual TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload& payload) const = 0;
[[nodiscard]] virtual sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const = 0;
[[nodiscard]] virtual TimeInterval
getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload& payload) const = 0;
[[nodiscard]] virtual bool requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const;
[[nodiscard]] sc_core::sc_time getCommandLength(Command command) const;
@@ -111,17 +124,21 @@ public:
protected:
MemSpec(const DRAMSys::Config::MemSpec& memSpec,
MemoryType memoryType,
unsigned numberOfChannels, unsigned pseudoChannelsPerChannel,
unsigned ranksPerChannel, unsigned banksPerRank,
unsigned groupsPerRank, unsigned banksPerGroup,
unsigned banksPerChannel, unsigned bankGroupsPerChannel,
unsigned devicesPerRank);
MemoryType memoryType,
unsigned numberOfChannels,
unsigned pseudoChannelsPerChannel,
unsigned ranksPerChannel,
unsigned banksPerRank,
unsigned groupsPerRank,
unsigned banksPerGroup,
unsigned banksPerChannel,
unsigned bankGroupsPerChannel,
unsigned devicesPerRank);
[[nodiscard]] static bool allBytesEnabled(const tlm::tlm_generic_payload& trans);
MemSpec(const MemSpec &) = default;
MemSpec(MemSpec &&) = default;
MemSpec(const MemSpec&) = default;
MemSpec(MemSpec&&) = default;
// Command lengths in cycles on bus, usually one clock cycle
std::vector<double> commandLengthInCycles;

View File

@@ -46,59 +46,64 @@ using namespace tlm;
namespace DRAMSys
{
MemSpecDDR3::MemSpecDDR3(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::DDR3,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD (tCKE),
tCKESR (tCK * memSpec.memtimingspec.entries.at("CKESR")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC (tCK * memSpec.memtimingspec.entries.at("RC")),
tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tXS (tCK * memSpec.memtimingspec.entries.at("XS")),
tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")),
tRFC (tCK * memSpec.memtimingspec.entries.at("RFC")),
tRP (tCK * memSpec.memtimingspec.entries.at("RP")),
tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tCCD (tCK * memSpec.memtimingspec.entries.at("CCD")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
tRRD (tCK * memSpec.memtimingspec.entries.at("RRD")),
tWTR (tCK * memSpec.memtimingspec.entries.at("WTR")),
tXPDLL (tCK * memSpec.memtimingspec.entries.at("XPDLL")),
tXSDLL (tCK * memSpec.memtimingspec.entries.at("XSDLL")),
tAL (tCK * memSpec.memtimingspec.entries.at("AL")),
tACTPDEN (tCK * memSpec.memtimingspec.entries.at("ACTPDEN")),
tPRPDEN (tCK * memSpec.memtimingspec.entries.at("PRPDEN")),
tREFPDEN (tCK * memSpec.memtimingspec.entries.at("REFPDEN")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")),
iDD0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd0") : 0),
iDD2N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n") : 0),
iDD3N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n") : 0),
iDD4R (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r") : 0),
iDD4W (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w") : 0),
iDD5 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd5") : 0),
iDD6 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd6") : 0),
vDD (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd") : 0),
iDD2P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p0") : 0),
iDD2P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p1") : 0),
iDD3P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p0") : 0),
iDD3P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p1") : 0)
MemSpecDDR3::MemSpecDDR3(const DRAMSys::Config::MemSpec& memSpec) :
MemSpec(memSpec,
MemoryType::DDR3,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tCKE(tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD(tCKE),
tCKESR(tCK * memSpec.memtimingspec.entries.at("CKESR")),
tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC(tCK * memSpec.memtimingspec.entries.at("RC")),
tRCD(tCK * memSpec.memtimingspec.entries.at("RCD")),
tRL(tCK * memSpec.memtimingspec.entries.at("RL")),
tRTP(tCK * memSpec.memtimingspec.entries.at("RTP")),
tWL(tCK * memSpec.memtimingspec.entries.at("WL")),
tWR(tCK * memSpec.memtimingspec.entries.at("WR")),
tXP(tCK * memSpec.memtimingspec.entries.at("XP")),
tXS(tCK * memSpec.memtimingspec.entries.at("XS")),
tREFI(tCK * memSpec.memtimingspec.entries.at("REFI")),
tRFC(tCK * memSpec.memtimingspec.entries.at("RFC")),
tRP(tCK * memSpec.memtimingspec.entries.at("RP")),
tDQSCK(tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tCCD(tCK * memSpec.memtimingspec.entries.at("CCD")),
tFAW(tCK * memSpec.memtimingspec.entries.at("FAW")),
tRRD(tCK * memSpec.memtimingspec.entries.at("RRD")),
tWTR(tCK * memSpec.memtimingspec.entries.at("WTR")),
tXPDLL(tCK * memSpec.memtimingspec.entries.at("XPDLL")),
tXSDLL(tCK * memSpec.memtimingspec.entries.at("XSDLL")),
tAL(tCK * memSpec.memtimingspec.entries.at("AL")),
tACTPDEN(tCK * memSpec.memtimingspec.entries.at("ACTPDEN")),
tPRPDEN(tCK * memSpec.memtimingspec.entries.at("PRPDEN")),
tREFPDEN(tCK * memSpec.memtimingspec.entries.at("REFPDEN")),
tRTRS(tCK * memSpec.memtimingspec.entries.at("RTRS")),
iDD0(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd0") : 0),
iDD2N(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n") : 0),
iDD3N(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n") : 0),
iDD4R(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r") : 0),
iDD4W(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w") : 0),
iDD5(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd5") : 0),
iDD6(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd6") : 0),
vDD(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd") : 0),
iDD2P0(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p0")
: 0),
iDD2P1(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p1")
: 0),
iDD3P0(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p0")
: 0),
iDD3P1(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p1") : 0)
{
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBits =
static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
memorySizeBytes = deviceSizeBytes * devicesPerRank * ranksPerChannel * numberOfChannels;
@@ -107,16 +112,17 @@ MemSpecDDR3::MemSpecDDR3(const DRAMSys::Config::MemSpec &memSpec)
std::cout << headline << std::endl;
std::cout << "Memory Configuration:" << std::endl << std::endl;
std::cout << " Memory type: " << "DDR3" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Memory type: "
<< "DDR3" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Ranks per channel: " << ranksPerChannel << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Rows per bank: " << rowsPerBank << std::endl;
std::cout << " Columns per row: " << columnsPerRow << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Devices per rank: " << devicesPerRank << std::endl;
std::cout << std::endl;
}
@@ -127,7 +133,8 @@ sc_time MemSpecDDR3::getRefreshIntervalAB() const
}
// Returns the execution time for commands that have a fixed execution time
sc_time MemSpecDDR3::getExecutionTime(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
sc_time MemSpecDDR3::getExecutionTime(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::PREPB || command == Command::PREAB)
return tRP;
@@ -150,18 +157,20 @@ sc_time MemSpecDDR3::getExecutionTime(Command command, [[maybe_unused]] const tl
if (command == Command::REFAB)
return tRFC;
SC_REPORT_FATAL("getExecutionTime",
"command not known or command doesn't have a fixed execution time");
throw;
}
TimeInterval MemSpecDDR3::getIntervalOnDataStrobe(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
TimeInterval
MemSpecDDR3::getIntervalOnDataStrobe(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::RD || command == Command::RDA)
return {tRL, tRL + burstDuration};
if (command == Command::WR || command == Command::WRA || command == Command::MWR || command == Command::MWRA)
if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
command == Command::MWRA)
return {tWL, tWL + burstDuration};
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");

View File

@@ -37,8 +37,8 @@
#ifndef MEMSPECDDR3_H
#define MEMSPECDDR3_H
#include "DRAMSys/configuration/memspec/MemSpec.h"
#include "DRAMSys/config/DRAMSysConfiguration.h"
#include "DRAMSys/configuration/memspec/MemSpec.h"
#include <systemc>
@@ -48,7 +48,7 @@ namespace DRAMSys
class MemSpecDDR3 final : public MemSpec
{
public:
explicit MemSpecDDR3(const DRAMSys::Config::MemSpec &memSpec);
explicit MemSpecDDR3(const DRAMSys::Config::MemSpec& memSpec);
// Memspec Variables:
const sc_core::sc_time tCKE;
@@ -95,8 +95,11 @@ public:
[[nodiscard]] sc_core::sc_time getRefreshIntervalAB() const override;
[[nodiscard]] sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] TimeInterval
getIntervalOnDataStrobe(Command command,
const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] bool requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const override;
};

View File

@@ -46,77 +46,83 @@ using namespace tlm;
namespace DRAMSys
{
MemSpecDDR4::MemSpecDDR4(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::DDR4,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
/ memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD (tCKE),
tCKESR (tCK * memSpec.memtimingspec.entries.at("CKESR")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC (tCK * memSpec.memtimingspec.entries.at("RC")),
tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
tRPRE (tCK * memSpec.memtimingspec.entries.at("RPRE")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tWPRE (tCK * memSpec.memtimingspec.entries.at("WPRE")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tXS (tCK * memSpec.memtimingspec.entries.at("XS")),
tREFI ((memSpec.memtimingspec.entries.at("REFM") == 4) ?
(tCK * (static_cast<double>(memSpec.memtimingspec.entries.at("REFI")) / 4)) :
((memSpec.memtimingspec.entries.at("REFM") == 2) ?
(tCK * (static_cast<double>(memSpec.memtimingspec.entries.at("REFI")) / 2)) :
(tCK * memSpec.memtimingspec.entries.at("REFI")))),
tRFC ((memSpec.memtimingspec.entries.at("REFM") == 4) ?
(tCK * memSpec.memtimingspec.entries.at("RFC4")) :
((memSpec.memtimingspec.entries.at("REFM") == 2) ?
(tCK * memSpec.memtimingspec.entries.at("RFC2")) :
(tCK * memSpec.memtimingspec.entries.at("RFC")))),
tRP (tCK * memSpec.memtimingspec.entries.at("RP")),
tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tCCD_S (tCK * memSpec.memtimingspec.entries.at("CCD_S")),
tCCD_L (tCK * memSpec.memtimingspec.entries.at("CCD_L")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
tRRD_S (tCK * memSpec.memtimingspec.entries.at("RRD_S")),
tRRD_L (tCK * memSpec.memtimingspec.entries.at("RRD_L")),
tWTR_S (tCK * memSpec.memtimingspec.entries.at("WTR_S")),
tWTR_L (tCK * memSpec.memtimingspec.entries.at("WTR_L")),
tAL (tCK * memSpec.memtimingspec.entries.at("AL")),
tXPDLL (tCK * memSpec.memtimingspec.entries.at("XPDLL")),
tXSDLL (tCK * memSpec.memtimingspec.entries.at("XSDLL")),
tACTPDEN (tCK * memSpec.memtimingspec.entries.at("ACTPDEN")),
tPRPDEN (tCK * memSpec.memtimingspec.entries.at("PRPDEN")),
tREFPDEN (tCK * memSpec.memtimingspec.entries.at("REFPDEN")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")),
iDD0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd0") : 0),
iDD2N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n") : 0),
iDD3N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n") : 0),
iDD4R (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r") : 0),
iDD4W (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w") : 0),
iDD5 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd5") : 0),
iDD6 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd6") : 0),
vDD (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd") : 0),
iDD02 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd02") : 0),
iDD2P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p0") : 0),
iDD2P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p1") : 0),
iDD3P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p0") : 0),
iDD3P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p1") : 0),
iDD62 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd62") : 0),
vDD2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd2") : 0)
MemSpecDDR4::MemSpecDDR4(const DRAMSys::Config::MemSpec& memSpec) :
MemSpec(memSpec,
MemoryType::DDR4,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") /
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tCKE(tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD(tCKE),
tCKESR(tCK * memSpec.memtimingspec.entries.at("CKESR")),
tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC(tCK * memSpec.memtimingspec.entries.at("RC")),
tRCD(tCK * memSpec.memtimingspec.entries.at("RCD")),
tRL(tCK * memSpec.memtimingspec.entries.at("RL")),
tRPRE(tCK * memSpec.memtimingspec.entries.at("RPRE")),
tRTP(tCK * memSpec.memtimingspec.entries.at("RTP")),
tWL(tCK * memSpec.memtimingspec.entries.at("WL")),
tWPRE(tCK * memSpec.memtimingspec.entries.at("WPRE")),
tWR(tCK * memSpec.memtimingspec.entries.at("WR")),
tXP(tCK * memSpec.memtimingspec.entries.at("XP")),
tXS(tCK * memSpec.memtimingspec.entries.at("XS")),
tREFI((memSpec.memtimingspec.entries.at("REFM") == 4)
? (tCK * (static_cast<double>(memSpec.memtimingspec.entries.at("REFI")) / 4))
: ((memSpec.memtimingspec.entries.at("REFM") == 2)
? (tCK * (static_cast<double>(memSpec.memtimingspec.entries.at("REFI")) / 2))
: (tCK * memSpec.memtimingspec.entries.at("REFI")))),
tRFC((memSpec.memtimingspec.entries.at("REFM") == 4)
? (tCK * memSpec.memtimingspec.entries.at("RFC4"))
: ((memSpec.memtimingspec.entries.at("REFM") == 2)
? (tCK * memSpec.memtimingspec.entries.at("RFC2"))
: (tCK * memSpec.memtimingspec.entries.at("RFC")))),
tRP(tCK * memSpec.memtimingspec.entries.at("RP")),
tDQSCK(tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tCCD_S(tCK * memSpec.memtimingspec.entries.at("CCD_S")),
tCCD_L(tCK * memSpec.memtimingspec.entries.at("CCD_L")),
tFAW(tCK * memSpec.memtimingspec.entries.at("FAW")),
tRRD_S(tCK * memSpec.memtimingspec.entries.at("RRD_S")),
tRRD_L(tCK * memSpec.memtimingspec.entries.at("RRD_L")),
tWTR_S(tCK * memSpec.memtimingspec.entries.at("WTR_S")),
tWTR_L(tCK * memSpec.memtimingspec.entries.at("WTR_L")),
tAL(tCK * memSpec.memtimingspec.entries.at("AL")),
tXPDLL(tCK * memSpec.memtimingspec.entries.at("XPDLL")),
tXSDLL(tCK * memSpec.memtimingspec.entries.at("XSDLL")),
tACTPDEN(tCK * memSpec.memtimingspec.entries.at("ACTPDEN")),
tPRPDEN(tCK * memSpec.memtimingspec.entries.at("PRPDEN")),
tREFPDEN(tCK * memSpec.memtimingspec.entries.at("REFPDEN")),
tRTRS(tCK * memSpec.memtimingspec.entries.at("RTRS")),
iDD0(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd0") : 0),
iDD2N(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n") : 0),
iDD3N(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n") : 0),
iDD4R(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r") : 0),
iDD4W(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w") : 0),
iDD5(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd5") : 0),
iDD6(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd6") : 0),
vDD(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd") : 0),
iDD02(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd02") : 0),
iDD2P0(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p0")
: 0),
iDD2P1(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p1")
: 0),
iDD3P0(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p0")
: 0),
iDD3P1(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p1")
: 0),
iDD62(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd62") : 0),
vDD2(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd2") : 0)
{
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBits =
static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
memorySizeBytes = deviceSizeBytes * devicesPerRank * ranksPerChannel * numberOfChannels;
@@ -125,17 +131,18 @@ MemSpecDDR4::MemSpecDDR4(const DRAMSys::Config::MemSpec &memSpec)
std::cout << headline << std::endl;
std::cout << "Memory Configuration:" << std::endl << std::endl;
std::cout << " Memory type: " << "DDR4" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Memory type: "
<< "DDR4" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Ranks per channel: " << ranksPerChannel << std::endl;
std::cout << " Bank groups per rank: " << groupsPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Bank groups per rank: " << groupsPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Rows per bank: " << rowsPerBank << std::endl;
std::cout << " Columns per row: " << columnsPerRow << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Devices per rank: " << devicesPerRank << std::endl;
std::cout << std::endl;
}
@@ -146,7 +153,8 @@ sc_time MemSpecDDR4::getRefreshIntervalAB() const
}
// Returns the execution time for commands that have a fixed execution time
sc_time MemSpecDDR4::getExecutionTime(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
sc_time MemSpecDDR4::getExecutionTime(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::PREPB || command == Command::PREAB)
return tRP;
@@ -174,12 +182,15 @@ sc_time MemSpecDDR4::getExecutionTime(Command command, [[maybe_unused]] const tl
throw;
}
TimeInterval MemSpecDDR4::getIntervalOnDataStrobe(Command command, [[maybe_unused]] const tlm::tlm_generic_payload & payload) const
TimeInterval
MemSpecDDR4::getIntervalOnDataStrobe(Command command,
[[maybe_unused]] const tlm::tlm_generic_payload& payload) const
{
if (command == Command::RD || command == Command::RDA)
return {tRL, tRL + burstDuration};
if (command == Command::WR || command == Command::WRA || command == Command::MWR || command == Command::MWRA)
if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
command == Command::MWRA)
return {tWL, tWL + burstDuration};
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");

View File

@@ -47,7 +47,7 @@ namespace DRAMSys
class MemSpecDDR4 final : public MemSpec
{
public:
explicit MemSpecDDR4(const DRAMSys::Config::MemSpec &memSpec);
explicit MemSpecDDR4(const DRAMSys::Config::MemSpec& memSpec);
// Memspec Variables:
const sc_core::sc_time tCKE;
@@ -102,8 +102,11 @@ public:
[[nodiscard]] sc_core::sc_time getRefreshIntervalAB() const override;
[[nodiscard]] sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] TimeInterval
getIntervalOnDataStrobe(Command command,
const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] bool requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const override;
};

View File

@@ -46,72 +46,75 @@ using namespace tlm;
namespace DRAMSys
{
MemSpecGDDR5::MemSpecGDDR5(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::GDDR5,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
/ memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tRP (tCK * memSpec.memtimingspec.entries.at("RP")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC (tCK * memSpec.memtimingspec.entries.at("RC")),
tRCDRD (tCK * memSpec.memtimingspec.entries.at("RCDRD")),
tRCDWR (tCK * memSpec.memtimingspec.entries.at("RCDWR")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tRRDS (tCK * memSpec.memtimingspec.entries.at("RRDS")),
tRRDL (tCK * memSpec.memtimingspec.entries.at("RRDL")),
tCCDS (tCK * memSpec.memtimingspec.entries.at("CCDS")),
tCCDL (tCK * memSpec.memtimingspec.entries.at("CCDL")),
tCL (tCK * memSpec.memtimingspec.entries.at("CL")),
tWCK2CKPIN (tCK * memSpec.memtimingspec.entries.at("WCK2CKPIN")),
tWCK2CK (tCK * memSpec.memtimingspec.entries.at("WCK2CK")),
tWCK2DQO (tCK * memSpec.memtimingspec.entries.at("WCK2DQO")),
tRTW (tCK * memSpec.memtimingspec.entries.at("RTW")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tWCK2DQI (tCK * memSpec.memtimingspec.entries.at("WCK2DQI")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tWTRS (tCK * memSpec.memtimingspec.entries.at("WTRS")),
tWTRL (tCK * memSpec.memtimingspec.entries.at("WTRL")),
tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD (tCK * memSpec.memtimingspec.entries.at("PD")),
tXPN (tCK * memSpec.memtimingspec.entries.at("XPN")),
tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")),
tREFIPB (tCK * memSpec.memtimingspec.entries.at("REFIPB")),
tRFC (tCK * memSpec.memtimingspec.entries.at("RFC")),
tRFCPB (tCK * memSpec.memtimingspec.entries.at("RFCPB")),
tRREFD (tCK * memSpec.memtimingspec.entries.at("RREFD")),
tXS (tCK * memSpec.memtimingspec.entries.at("XS")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
t32AW (tCK * memSpec.memtimingspec.entries.at("32AW")),
tPPD (tCK * memSpec.memtimingspec.entries.at("PPD")),
tLK (tCK * memSpec.memtimingspec.entries.at("LK")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS"))
MemSpecGDDR5::MemSpecGDDR5(const DRAMSys::Config::MemSpec& memSpec) :
MemSpec(memSpec,
MemoryType::GDDR5,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") /
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tRP(tCK * memSpec.memtimingspec.entries.at("RP")),
tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC(tCK * memSpec.memtimingspec.entries.at("RC")),
tRCDRD(tCK * memSpec.memtimingspec.entries.at("RCDRD")),
tRCDWR(tCK * memSpec.memtimingspec.entries.at("RCDWR")),
tRTP(tCK * memSpec.memtimingspec.entries.at("RTP")),
tRRDS(tCK * memSpec.memtimingspec.entries.at("RRDS")),
tRRDL(tCK * memSpec.memtimingspec.entries.at("RRDL")),
tCCDS(tCK * memSpec.memtimingspec.entries.at("CCDS")),
tCCDL(tCK * memSpec.memtimingspec.entries.at("CCDL")),
tCL(tCK * memSpec.memtimingspec.entries.at("CL")),
tWCK2CKPIN(tCK * memSpec.memtimingspec.entries.at("WCK2CKPIN")),
tWCK2CK(tCK * memSpec.memtimingspec.entries.at("WCK2CK")),
tWCK2DQO(tCK * memSpec.memtimingspec.entries.at("WCK2DQO")),
tRTW(tCK * memSpec.memtimingspec.entries.at("RTW")),
tWL(tCK * memSpec.memtimingspec.entries.at("WL")),
tWCK2DQI(tCK * memSpec.memtimingspec.entries.at("WCK2DQI")),
tWR(tCK * memSpec.memtimingspec.entries.at("WR")),
tWTRS(tCK * memSpec.memtimingspec.entries.at("WTRS")),
tWTRL(tCK * memSpec.memtimingspec.entries.at("WTRL")),
tCKE(tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD(tCK * memSpec.memtimingspec.entries.at("PD")),
tXPN(tCK * memSpec.memtimingspec.entries.at("XPN")),
tREFI(tCK * memSpec.memtimingspec.entries.at("REFI")),
tREFIPB(tCK * memSpec.memtimingspec.entries.at("REFIPB")),
tRFC(tCK * memSpec.memtimingspec.entries.at("RFC")),
tRFCPB(tCK * memSpec.memtimingspec.entries.at("RFCPB")),
tRREFD(tCK * memSpec.memtimingspec.entries.at("RREFD")),
tXS(tCK * memSpec.memtimingspec.entries.at("XS")),
tFAW(tCK * memSpec.memtimingspec.entries.at("FAW")),
t32AW(tCK * memSpec.memtimingspec.entries.at("32AW")),
tPPD(tCK * memSpec.memtimingspec.entries.at("PPD")),
tLK(tCK * memSpec.memtimingspec.entries.at("LK")),
tRTRS(tCK * memSpec.memtimingspec.entries.at("RTRS"))
{
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBits =
static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
memorySizeBytes = deviceSizeBytes * ranksPerChannel * numberOfChannels;
std::cout << headline << std::endl;
std::cout << "Memory Configuration:" << std::endl << std::endl;
std::cout << " Memory type: " << "GDDR5" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Memory type: "
<< "GDDR5" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Ranks per channel: " << ranksPerChannel << std::endl;
std::cout << " Bank groups per rank: " << groupsPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Bank groups per rank: " << groupsPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Rows per bank: " << rowsPerBank << std::endl;
std::cout << " Columns per row: " << columnsPerRow << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Devices per rank: " << devicesPerRank << std::endl;
std::cout << std::endl;
}
@@ -126,7 +129,7 @@ sc_time MemSpecGDDR5::getRefreshIntervalPB() const
return tREFIPB;
}
sc_time MemSpecGDDR5::getExecutionTime(Command command, const tlm_generic_payload &payload) const
sc_time MemSpecGDDR5::getExecutionTime(Command command, const tlm_generic_payload& payload) const
{
if (command == Command::PREPB || command == Command::PREAB)
return tRP;
@@ -162,13 +165,17 @@ sc_time MemSpecGDDR5::getExecutionTime(Command command, const tlm_generic_payloa
throw;
}
TimeInterval MemSpecGDDR5::getIntervalOnDataStrobe(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
TimeInterval
MemSpecGDDR5::getIntervalOnDataStrobe(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::RD || command == Command::RDA)
return {tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO, tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + burstDuration};
return {tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,
tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + burstDuration};
if (command == Command::WR || command == Command::WRA)
return {tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI, tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + burstDuration};
return {tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI,
tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + burstDuration};
SC_REPORT_FATAL("MemSpecGDDR5", "Method was called with invalid argument");
throw;

View File

@@ -47,7 +47,7 @@ namespace DRAMSys
class MemSpecGDDR5 final : public MemSpec
{
public:
explicit MemSpecGDDR5(const DRAMSys::Config::MemSpec &memSpec);
explicit MemSpecGDDR5(const DRAMSys::Config::MemSpec& memSpec);
// Memspec Variables:
const sc_core::sc_time tRP;
@@ -81,8 +81,8 @@ public:
const sc_core::sc_time tXS;
const sc_core::sc_time tFAW;
const sc_core::sc_time t32AW;
// sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK;
// sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK;
// sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK;
// sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK;
const sc_core::sc_time tPPD;
const sc_core::sc_time tLK;
const sc_core::sc_time tRTRS;
@@ -93,8 +93,11 @@ public:
[[nodiscard]] sc_core::sc_time getRefreshIntervalAB() const override;
[[nodiscard]] sc_core::sc_time getRefreshIntervalPB() const override;
[[nodiscard]] sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] TimeInterval
getIntervalOnDataStrobe(Command command,
const tlm::tlm_generic_payload& payload) const override;
};
} // namespace DRAMSys

View File

@@ -46,72 +46,75 @@ using namespace tlm;
namespace DRAMSys
{
MemSpecGDDR5X::MemSpecGDDR5X(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::GDDR5X,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
/ memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tRP (tCK * memSpec.memtimingspec.entries.at("RP")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC (tCK * memSpec.memtimingspec.entries.at("RC")),
tRCDRD (tCK * memSpec.memtimingspec.entries.at("RCDRD")),
tRCDWR (tCK * memSpec.memtimingspec.entries.at("RCDWR")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tRRDS (tCK * memSpec.memtimingspec.entries.at("RRDS")),
tRRDL (tCK * memSpec.memtimingspec.entries.at("RRDL")),
tCCDS (tCK * memSpec.memtimingspec.entries.at("CCDS")),
tCCDL (tCK * memSpec.memtimingspec.entries.at("CCDL")),
tRL (tCK * memSpec.memtimingspec.entries.at("CL")),
tWCK2CKPIN (tCK * memSpec.memtimingspec.entries.at("WCK2CKPIN")),
tWCK2CK (tCK * memSpec.memtimingspec.entries.at("WCK2CK")),
tWCK2DQO (tCK * memSpec.memtimingspec.entries.at("WCK2DQO")),
tRTW (tCK * memSpec.memtimingspec.entries.at("RTW")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tWCK2DQI (tCK * memSpec.memtimingspec.entries.at("WCK2DQI")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tWTRS (tCK * memSpec.memtimingspec.entries.at("WTRS")),
tWTRL (tCK * memSpec.memtimingspec.entries.at("WTRL")),
tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD (tCK * memSpec.memtimingspec.entries.at("PD")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")),
tREFIPB (tCK * memSpec.memtimingspec.entries.at("REFIPB")),
tRFC (tCK * memSpec.memtimingspec.entries.at("RFC")),
tRFCPB (tCK * memSpec.memtimingspec.entries.at("RFCPB")),
tRREFD (tCK * memSpec.memtimingspec.entries.at("RREFD")),
tXS (tCK * memSpec.memtimingspec.entries.at("XS")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
t32AW (tCK * memSpec.memtimingspec.entries.at("32AW")),
tPPD (tCK * memSpec.memtimingspec.entries.at("PPD")),
tLK (tCK * memSpec.memtimingspec.entries.at("LK")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("TRS"))
MemSpecGDDR5X::MemSpecGDDR5X(const DRAMSys::Config::MemSpec& memSpec) :
MemSpec(memSpec,
MemoryType::GDDR5X,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") /
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tRP(tCK * memSpec.memtimingspec.entries.at("RP")),
tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC(tCK * memSpec.memtimingspec.entries.at("RC")),
tRCDRD(tCK * memSpec.memtimingspec.entries.at("RCDRD")),
tRCDWR(tCK * memSpec.memtimingspec.entries.at("RCDWR")),
tRTP(tCK * memSpec.memtimingspec.entries.at("RTP")),
tRRDS(tCK * memSpec.memtimingspec.entries.at("RRDS")),
tRRDL(tCK * memSpec.memtimingspec.entries.at("RRDL")),
tCCDS(tCK * memSpec.memtimingspec.entries.at("CCDS")),
tCCDL(tCK * memSpec.memtimingspec.entries.at("CCDL")),
tRL(tCK * memSpec.memtimingspec.entries.at("CL")),
tWCK2CKPIN(tCK * memSpec.memtimingspec.entries.at("WCK2CKPIN")),
tWCK2CK(tCK * memSpec.memtimingspec.entries.at("WCK2CK")),
tWCK2DQO(tCK * memSpec.memtimingspec.entries.at("WCK2DQO")),
tRTW(tCK * memSpec.memtimingspec.entries.at("RTW")),
tWL(tCK * memSpec.memtimingspec.entries.at("WL")),
tWCK2DQI(tCK * memSpec.memtimingspec.entries.at("WCK2DQI")),
tWR(tCK * memSpec.memtimingspec.entries.at("WR")),
tWTRS(tCK * memSpec.memtimingspec.entries.at("WTRS")),
tWTRL(tCK * memSpec.memtimingspec.entries.at("WTRL")),
tCKE(tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD(tCK * memSpec.memtimingspec.entries.at("PD")),
tXP(tCK * memSpec.memtimingspec.entries.at("XP")),
tREFI(tCK * memSpec.memtimingspec.entries.at("REFI")),
tREFIPB(tCK * memSpec.memtimingspec.entries.at("REFIPB")),
tRFC(tCK * memSpec.memtimingspec.entries.at("RFC")),
tRFCPB(tCK * memSpec.memtimingspec.entries.at("RFCPB")),
tRREFD(tCK * memSpec.memtimingspec.entries.at("RREFD")),
tXS(tCK * memSpec.memtimingspec.entries.at("XS")),
tFAW(tCK * memSpec.memtimingspec.entries.at("FAW")),
t32AW(tCK * memSpec.memtimingspec.entries.at("32AW")),
tPPD(tCK * memSpec.memtimingspec.entries.at("PPD")),
tLK(tCK * memSpec.memtimingspec.entries.at("LK")),
tRTRS(tCK * memSpec.memtimingspec.entries.at("TRS"))
{
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBits =
static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
memorySizeBytes = deviceSizeBytes * ranksPerChannel * numberOfChannels;
std::cout << headline << std::endl;
std::cout << "Memory Configuration:" << std::endl << std::endl;
std::cout << " Memory type: " << "GDDR5X" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Memory type: "
<< "GDDR5X" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Ranks per channel: " << ranksPerChannel << std::endl;
std::cout << " Bank groups per rank: " << groupsPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Bank groups per rank: " << groupsPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Rows per bank: " << rowsPerBank << std::endl;
std::cout << " Columns per row: " << columnsPerRow << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Devices per rank: " << devicesPerRank << std::endl;
std::cout << std::endl;
}
@@ -126,7 +129,7 @@ sc_time MemSpecGDDR5X::getRefreshIntervalPB() const
return tREFIPB;
}
sc_time MemSpecGDDR5X::getExecutionTime(Command command, const tlm_generic_payload &payload) const
sc_time MemSpecGDDR5X::getExecutionTime(Command command, const tlm_generic_payload& payload) const
{
if (command == Command::PREPB || command == Command::PREAB)
return tRP;
@@ -162,13 +165,17 @@ sc_time MemSpecGDDR5X::getExecutionTime(Command command, const tlm_generic_paylo
throw;
}
TimeInterval MemSpecGDDR5X::getIntervalOnDataStrobe(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
TimeInterval
MemSpecGDDR5X::getIntervalOnDataStrobe(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::RD || command == Command::RDA)
return {tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO, tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + burstDuration};
return {tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,
tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + burstDuration};
if (command == Command::WR || command == Command::WRA)
return {tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI, tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + burstDuration};
return {tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI,
tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + burstDuration};
SC_REPORT_FATAL("MemSpecGDDR5X", "Method was called with invalid argument");
throw;

View File

@@ -47,7 +47,7 @@ namespace DRAMSys
class MemSpecGDDR5X final : public MemSpec
{
public:
explicit MemSpecGDDR5X(const DRAMSys::Config::MemSpec &memSpec);
explicit MemSpecGDDR5X(const DRAMSys::Config::MemSpec& memSpec);
// Memspec Variables:
const sc_core::sc_time tRP;
@@ -81,8 +81,8 @@ public:
const sc_core::sc_time tXS;
const sc_core::sc_time tFAW;
const sc_core::sc_time t32AW;
// sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK;
// sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK;
// sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK;
// sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK;
const sc_core::sc_time tPPD;
const sc_core::sc_time tLK;
const sc_core::sc_time tRTRS;
@@ -93,8 +93,11 @@ public:
[[nodiscard]] sc_core::sc_time getRefreshIntervalAB() const override;
[[nodiscard]] sc_core::sc_time getRefreshIntervalPB() const override;
[[nodiscard]] sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] TimeInterval
getIntervalOnDataStrobe(Command command,
const tlm::tlm_generic_payload& payload) const override;
};
} // namespace DRAMSys

View File

@@ -46,75 +46,78 @@ using namespace tlm;
namespace DRAMSys
{
MemSpecGDDR6::MemSpecGDDR6(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::GDDR6,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at( "nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
/ memSpec.memarchitecturespec.entries.at( "nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at( "nbrOfBankGroups")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tRP (tCK * memSpec.memtimingspec.entries.at("RP")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC (tCK * memSpec.memtimingspec.entries.at("RC")),
tRCDRD (tCK * memSpec.memtimingspec.entries.at("RCDRD")),
tRCDWR (tCK * memSpec.memtimingspec.entries.at("RCDWR")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tRRDS (tCK * memSpec.memtimingspec.entries.at("RRDS")),
tRRDL (tCK * memSpec.memtimingspec.entries.at("RRDL")),
tCCDS (tCK * memSpec.memtimingspec.entries.at("CCDS")),
tCCDL (tCK * memSpec.memtimingspec.entries.at("CCDL")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
tWCK2CKPIN (tCK * memSpec.memtimingspec.entries.at("WCK2CKPIN")),
tWCK2CK (tCK * memSpec.memtimingspec.entries.at("WCK2CK")),
tWCK2DQO (tCK * memSpec.memtimingspec.entries.at("WCK2DQO")),
tRTW (tCK * memSpec.memtimingspec.entries.at("RTW")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tWCK2DQI (tCK * memSpec.memtimingspec.entries.at("WCK2DQI")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tWTRS (tCK * memSpec.memtimingspec.entries.at("WTRS")),
tWTRL (tCK * memSpec.memtimingspec.entries.at("WTRL")),
tPD (tCK * memSpec.memtimingspec.entries.at("PD")),
tCKESR (tCK * memSpec.memtimingspec.entries.at("CKESR")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")),
tREFIpb (tCK * memSpec.memtimingspec.entries.at("REFIpb")),
tRFCab (tCK * memSpec.memtimingspec.entries.at("RFCab")),
tRFCpb (tCK * memSpec.memtimingspec.entries.at("RFCpb")),
tRREFD (tCK * memSpec.memtimingspec.entries.at("RREFD")),
tXS (tCK * memSpec.memtimingspec.entries.at("XS")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
tPPD (tCK * memSpec.memtimingspec.entries.at("PPD")),
tLK (tCK * memSpec.memtimingspec.entries.at("LK")),
tACTPDE (tCK * memSpec.memtimingspec.entries.at("ACTPDE")),
tPREPDE (tCK * memSpec.memtimingspec.entries.at("PREPDE")),
tREFPDE (tCK * memSpec.memtimingspec.entries.at("REFPDE")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")),
per2BankOffset(memSpec.memarchitecturespec.entries.at("per2BankOffset"))
MemSpecGDDR6::MemSpecGDDR6(const DRAMSys::Config::MemSpec& memSpec) :
MemSpec(memSpec,
MemoryType::GDDR6,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") /
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tRP(tCK * memSpec.memtimingspec.entries.at("RP")),
tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC(tCK * memSpec.memtimingspec.entries.at("RC")),
tRCDRD(tCK * memSpec.memtimingspec.entries.at("RCDRD")),
tRCDWR(tCK * memSpec.memtimingspec.entries.at("RCDWR")),
tRTP(tCK * memSpec.memtimingspec.entries.at("RTP")),
tRRDS(tCK * memSpec.memtimingspec.entries.at("RRDS")),
tRRDL(tCK * memSpec.memtimingspec.entries.at("RRDL")),
tCCDS(tCK * memSpec.memtimingspec.entries.at("CCDS")),
tCCDL(tCK * memSpec.memtimingspec.entries.at("CCDL")),
tRL(tCK * memSpec.memtimingspec.entries.at("RL")),
tWCK2CKPIN(tCK * memSpec.memtimingspec.entries.at("WCK2CKPIN")),
tWCK2CK(tCK * memSpec.memtimingspec.entries.at("WCK2CK")),
tWCK2DQO(tCK * memSpec.memtimingspec.entries.at("WCK2DQO")),
tRTW(tCK * memSpec.memtimingspec.entries.at("RTW")),
tWL(tCK * memSpec.memtimingspec.entries.at("WL")),
tWCK2DQI(tCK * memSpec.memtimingspec.entries.at("WCK2DQI")),
tWR(tCK * memSpec.memtimingspec.entries.at("WR")),
tWTRS(tCK * memSpec.memtimingspec.entries.at("WTRS")),
tWTRL(tCK * memSpec.memtimingspec.entries.at("WTRL")),
tPD(tCK * memSpec.memtimingspec.entries.at("PD")),
tCKESR(tCK * memSpec.memtimingspec.entries.at("CKESR")),
tXP(tCK * memSpec.memtimingspec.entries.at("XP")),
tREFI(tCK * memSpec.memtimingspec.entries.at("REFI")),
tREFIpb(tCK * memSpec.memtimingspec.entries.at("REFIpb")),
tRFCab(tCK * memSpec.memtimingspec.entries.at("RFCab")),
tRFCpb(tCK * memSpec.memtimingspec.entries.at("RFCpb")),
tRREFD(tCK * memSpec.memtimingspec.entries.at("RREFD")),
tXS(tCK * memSpec.memtimingspec.entries.at("XS")),
tFAW(tCK * memSpec.memtimingspec.entries.at("FAW")),
tPPD(tCK * memSpec.memtimingspec.entries.at("PPD")),
tLK(tCK * memSpec.memtimingspec.entries.at("LK")),
tACTPDE(tCK * memSpec.memtimingspec.entries.at("ACTPDE")),
tPREPDE(tCK * memSpec.memtimingspec.entries.at("PREPDE")),
tREFPDE(tCK * memSpec.memtimingspec.entries.at("REFPDE")),
tRTRS(tCK * memSpec.memtimingspec.entries.at("RTRS")),
per2BankOffset(memSpec.memarchitecturespec.entries.at("per2BankOffset"))
{
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBits =
static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
memorySizeBytes = deviceSizeBytes * ranksPerChannel * numberOfChannels;
std::cout << headline << std::endl;
std::cout << "Memory Configuration:" << std::endl << std::endl;
std::cout << " Memory type: " << "GDDR6" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Memory type: "
<< "GDDR6" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Ranks per channel: " << ranksPerChannel << std::endl;
std::cout << " Bank groups per rank: " << groupsPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Bank groups per rank: " << groupsPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Rows per bank: " << rowsPerBank << std::endl;
std::cout << " Columns per row: " << columnsPerRow << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Devices per rank: " << devicesPerRank << std::endl;
std::cout << std::endl;
}
@@ -139,7 +142,7 @@ unsigned MemSpecGDDR6::getPer2BankOffset() const
return per2BankOffset;
}
sc_time MemSpecGDDR6::getExecutionTime(Command command, const tlm_generic_payload &payload) const
sc_time MemSpecGDDR6::getExecutionTime(Command command, const tlm_generic_payload& payload) const
{
if (command == Command::PREPB || command == Command::PREAB)
return tRP;
@@ -175,13 +178,17 @@ sc_time MemSpecGDDR6::getExecutionTime(Command command, const tlm_generic_payloa
throw;
}
TimeInterval MemSpecGDDR6::getIntervalOnDataStrobe(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
TimeInterval
MemSpecGDDR6::getIntervalOnDataStrobe(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::RD || command == Command::RDA)
return {tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO, tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + burstDuration};
return {tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO,
tRL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + burstDuration};
if (command == Command::WR || command == Command::WRA)
return {tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI, tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + burstDuration};
return {tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI,
tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + burstDuration};
SC_REPORT_FATAL("MemSpecGDDR6", "Method was called with invalid argument");
throw;

View File

@@ -46,7 +46,7 @@ namespace DRAMSys
struct MemSpecGDDR6 final : public MemSpec
{
public:
explicit MemSpecGDDR6(const DRAMSys::Config::MemSpec &memSpec);
explicit MemSpecGDDR6(const DRAMSys::Config::MemSpec& memSpec);
// Memspec Variables:
const sc_core::sc_time tRP;
@@ -79,8 +79,8 @@ public:
const sc_core::sc_time tRREFD;
const sc_core::sc_time tXS;
const sc_core::sc_time tFAW;
// sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK;
// sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK;
// sc_time tRDSRE; // = tCL + tWCK2CKPIN + tWCK2CK + tWCK2DQO + BurstLength / DataRate * tCK;
// sc_time tWRSRE; // = tWL + tWCK2CKPIN + tWCK2CK + tWCK2DQI + BurstLength / DataRate * tCK;
const sc_core::sc_time tPPD;
const sc_core::sc_time tLK;
const sc_core::sc_time tACTPDE;
@@ -96,8 +96,11 @@ public:
[[nodiscard]] sc_core::sc_time getRefreshIntervalP2B() const override;
[[nodiscard]] unsigned getPer2BankOffset() const override;
[[nodiscard]] sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] TimeInterval
getIntervalOnDataStrobe(Command command,
const tlm::tlm_generic_payload& payload) const override;
private:
unsigned per2BankOffset;

View File

@@ -46,69 +46,72 @@ using namespace tlm;
namespace DRAMSys
{
MemSpecHBM2::MemSpecHBM2(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::HBM2,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
/ memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups")
* memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tRC (tCK * memSpec.memtimingspec.entries.at("RC")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRCDRD (tCK * memSpec.memtimingspec.entries.at("RCDRD")),
tRCDWR (tCK * memSpec.memtimingspec.entries.at("RCDWR")),
tRRDL (tCK * memSpec.memtimingspec.entries.at("RRDL")),
tRRDS (tCK * memSpec.memtimingspec.entries.at("RRDS")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tRP (tCK * memSpec.memtimingspec.entries.at("RP")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tPL (tCK * memSpec.memtimingspec.entries.at("PL")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tCCDL (tCK * memSpec.memtimingspec.entries.at("CCDL")),
tCCDS (tCK * memSpec.memtimingspec.entries.at("CCDS")),
tWTRL (tCK * memSpec.memtimingspec.entries.at("WTRL")),
tWTRS (tCK * memSpec.memtimingspec.entries.at("WTRS")),
tRTW (tCK * memSpec.memtimingspec.entries.at("RTW")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD (tCKE),
tCKESR (tCKE + tCK),
tXS (tCK * memSpec.memtimingspec.entries.at("XS")),
tRFC (tCK * memSpec.memtimingspec.entries.at("RFC")),
tRFCSB (tCK * memSpec.memtimingspec.entries.at("RFCSB")),
tRREFD (tCK * memSpec.memtimingspec.entries.at("RREFD")),
tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")),
tREFISB (tCK * memSpec.memtimingspec.entries.at("REFISB"))
MemSpecHBM2::MemSpecHBM2(const DRAMSys::Config::MemSpec& memSpec) :
MemSpec(memSpec,
MemoryType::HBM2,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") /
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") *
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfBankGroups") *
memSpec.memarchitecturespec.entries.at("nbrOfPseudoChannels"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tDQSCK(tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tRC(tCK * memSpec.memtimingspec.entries.at("RC")),
tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")),
tRCDRD(tCK * memSpec.memtimingspec.entries.at("RCDRD")),
tRCDWR(tCK * memSpec.memtimingspec.entries.at("RCDWR")),
tRRDL(tCK * memSpec.memtimingspec.entries.at("RRDL")),
tRRDS(tCK * memSpec.memtimingspec.entries.at("RRDS")),
tFAW(tCK * memSpec.memtimingspec.entries.at("FAW")),
tRTP(tCK * memSpec.memtimingspec.entries.at("RTP")),
tRP(tCK * memSpec.memtimingspec.entries.at("RP")),
tRL(tCK * memSpec.memtimingspec.entries.at("RL")),
tWL(tCK * memSpec.memtimingspec.entries.at("WL")),
tPL(tCK * memSpec.memtimingspec.entries.at("PL")),
tWR(tCK * memSpec.memtimingspec.entries.at("WR")),
tCCDL(tCK * memSpec.memtimingspec.entries.at("CCDL")),
tCCDS(tCK * memSpec.memtimingspec.entries.at("CCDS")),
tWTRL(tCK * memSpec.memtimingspec.entries.at("WTRL")),
tWTRS(tCK * memSpec.memtimingspec.entries.at("WTRS")),
tRTW(tCK * memSpec.memtimingspec.entries.at("RTW")),
tXP(tCK * memSpec.memtimingspec.entries.at("XP")),
tCKE(tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD(tCKE),
tCKESR(tCKE + tCK),
tXS(tCK * memSpec.memtimingspec.entries.at("XS")),
tRFC(tCK * memSpec.memtimingspec.entries.at("RFC")),
tRFCSB(tCK * memSpec.memtimingspec.entries.at("RFCSB")),
tRREFD(tCK * memSpec.memtimingspec.entries.at("RREFD")),
tREFI(tCK * memSpec.memtimingspec.entries.at("REFI")),
tREFISB(tCK * memSpec.memtimingspec.entries.at("REFISB"))
{
commandLengthInCycles[Command::ACT] = 2;
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBits =
static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
memorySizeBytes = deviceSizeBytes * ranksPerChannel * numberOfChannels;
std::cout << headline << std::endl;
std::cout << "Memory Configuration:" << std::endl << std::endl;
std::cout << " Memory type: " << "HBM2" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Memory type: "
<< "HBM2" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Pseudo channels per channel: " << ranksPerChannel << std::endl;
std::cout << " Bank groups per pseudo channel: " << groupsPerRank << std::endl;
std::cout << " Banks per pseudo channel: " << banksPerRank << std::endl;
std::cout << " Rows per bank: " << rowsPerBank << std::endl;
std::cout << " Columns per row: " << columnsPerRow << std::endl;
std::cout << " Pseudo channel width in bits: " << bitWidth << std::endl;
std::cout << " Pseudo channel size in bits: " << deviceSizeBits << std::endl;
std::cout << " Pseudo channel size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Pseudo channels per channel: " << ranksPerChannel << std::endl;
std::cout << " Bank groups per pseudo channel: " << groupsPerRank << std::endl;
std::cout << " Banks per pseudo channel: " << banksPerRank << std::endl;
std::cout << " Rows per bank: " << rowsPerBank << std::endl;
std::cout << " Columns per row: " << columnsPerRow << std::endl;
std::cout << " Pseudo channel width in bits: " << bitWidth << std::endl;
std::cout << " Pseudo channel size in bits: " << deviceSizeBits << std::endl;
std::cout << " Pseudo channel size in bytes: " << deviceSizeBytes << std::endl;
std::cout << std::endl;
}
@@ -127,7 +130,7 @@ bool MemSpecHBM2::hasRasAndCasBus() const
return true;
}
sc_time MemSpecHBM2::getExecutionTime(Command command, const tlm_generic_payload &payload) const
sc_time MemSpecHBM2::getExecutionTime(Command command, const tlm_generic_payload& payload) const
{
if (command == Command::PREPB || command == Command::PREAB)
return tRP;
@@ -163,12 +166,15 @@ sc_time MemSpecHBM2::getExecutionTime(Command command, const tlm_generic_payload
throw;
}
TimeInterval MemSpecHBM2::getIntervalOnDataStrobe(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
TimeInterval
MemSpecHBM2::getIntervalOnDataStrobe(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::RD || command == Command::RDA)
return {tRL + tDQSCK, tRL + tDQSCK + burstDuration};
if (command == Command::WR || command == Command::WRA || command == Command::MWR || command == Command::MWRA)
if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
command == Command::MWRA)
return {tWL, tWL + burstDuration};
SC_REPORT_FATAL("MemSpecHBM2", "Method was called with invalid argument");

View File

@@ -47,11 +47,11 @@ namespace DRAMSys
class MemSpecHBM2 final : public MemSpec
{
public:
explicit MemSpecHBM2(const DRAMSys::Config::MemSpec &memSpec);
explicit MemSpecHBM2(const DRAMSys::Config::MemSpec& memSpec);
// Memspec Variables:
const sc_core::sc_time tDQSCK;
// sc_time tDQSQ; // TODO: check actual value of this parameter
// sc_time tDQSQ; // TODO: check actual value of this parameter
const sc_core::sc_time tRC;
const sc_core::sc_time tRAS;
const sc_core::sc_time tRCDRD;
@@ -67,13 +67,13 @@ public:
const sc_core::sc_time tWR;
const sc_core::sc_time tCCDL;
const sc_core::sc_time tCCDS;
// sc_time tCCDR; // TODO: consecutive reads to different stack IDs
// sc_time tCCDR; // TODO: consecutive reads to different stack IDs
const sc_core::sc_time tWTRL;
const sc_core::sc_time tWTRS;
const sc_core::sc_time tRTW;
const sc_core::sc_time tXP;
const sc_core::sc_time tCKE;
const sc_core::sc_time tPD; // = tCKE;
const sc_core::sc_time tPD; // = tCKE;
const sc_core::sc_time tCKESR; // = tCKE + tCK;
const sc_core::sc_time tXS;
const sc_core::sc_time tRFC;
@@ -90,8 +90,11 @@ public:
[[nodiscard]] bool hasRasAndCasBus() const override;
[[nodiscard]] sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] TimeInterval
getIntervalOnDataStrobe(Command command,
const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] bool requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const override;
};

View File

@@ -46,50 +46,51 @@ using namespace tlm;
namespace DRAMSys
{
MemSpecLPDDR4::MemSpecLPDDR4(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::LPDDR4,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")),
tREFIpb (tCK * memSpec.memtimingspec.entries.at("REFIPB")),
tRFCab (tCK * memSpec.memtimingspec.entries.at("RFCAB")),
tRFCpb (tCK * memSpec.memtimingspec.entries.at("RFCPB")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRPab (tCK * memSpec.memtimingspec.entries.at("RPAB")),
tRPpb (tCK * memSpec.memtimingspec.entries.at("RPPB")),
tRCpb (tCK * memSpec.memtimingspec.entries.at("RCPB")),
tRCab (tCK * memSpec.memtimingspec.entries.at("RCAB")),
tPPD (tCK * memSpec.memtimingspec.entries.at("PPD")),
tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
tRRD (tCK * memSpec.memtimingspec.entries.at("RRD")),
tCCD (tCK * memSpec.memtimingspec.entries.at("CCD")),
tCCDMW (tCK * memSpec.memtimingspec.entries.at("CCDMW")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
tRPST (tCK * memSpec.memtimingspec.entries.at("RPST")),
tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tDQSS (tCK * memSpec.memtimingspec.entries.at("DQSS")),
tDQS2DQ (tCK * memSpec.memtimingspec.entries.at("DQS2DQ")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tWPRE (tCK * memSpec.memtimingspec.entries.at("WPRE")),
tWTR (tCK * memSpec.memtimingspec.entries.at("WTR")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tSR (tCK * memSpec.memtimingspec.entries.at("SR")),
tXSR (tCK * memSpec.memtimingspec.entries.at("XSR")),
tESCKE (tCK * memSpec.memtimingspec.entries.at("ESCKE")),
tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")),
tCMDCKE (tCK * memSpec.memtimingspec.entries.at("CMDCKE")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS"))
MemSpecLPDDR4::MemSpecLPDDR4(const DRAMSys::Config::MemSpec& memSpec) :
MemSpec(memSpec,
MemoryType::LPDDR4,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tREFI(tCK * memSpec.memtimingspec.entries.at("REFI")),
tREFIpb(tCK * memSpec.memtimingspec.entries.at("REFIPB")),
tRFCab(tCK * memSpec.memtimingspec.entries.at("RFCAB")),
tRFCpb(tCK * memSpec.memtimingspec.entries.at("RFCPB")),
tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")),
tRPab(tCK * memSpec.memtimingspec.entries.at("RPAB")),
tRPpb(tCK * memSpec.memtimingspec.entries.at("RPPB")),
tRCpb(tCK * memSpec.memtimingspec.entries.at("RCPB")),
tRCab(tCK * memSpec.memtimingspec.entries.at("RCAB")),
tPPD(tCK * memSpec.memtimingspec.entries.at("PPD")),
tRCD(tCK * memSpec.memtimingspec.entries.at("RCD")),
tFAW(tCK * memSpec.memtimingspec.entries.at("FAW")),
tRRD(tCK * memSpec.memtimingspec.entries.at("RRD")),
tCCD(tCK * memSpec.memtimingspec.entries.at("CCD")),
tCCDMW(tCK * memSpec.memtimingspec.entries.at("CCDMW")),
tRL(tCK * memSpec.memtimingspec.entries.at("RL")),
tRPST(tCK * memSpec.memtimingspec.entries.at("RPST")),
tDQSCK(tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tRTP(tCK * memSpec.memtimingspec.entries.at("RTP")),
tWL(tCK * memSpec.memtimingspec.entries.at("WL")),
tDQSS(tCK * memSpec.memtimingspec.entries.at("DQSS")),
tDQS2DQ(tCK * memSpec.memtimingspec.entries.at("DQS2DQ")),
tWR(tCK * memSpec.memtimingspec.entries.at("WR")),
tWPRE(tCK * memSpec.memtimingspec.entries.at("WPRE")),
tWTR(tCK * memSpec.memtimingspec.entries.at("WTR")),
tXP(tCK * memSpec.memtimingspec.entries.at("XP")),
tSR(tCK * memSpec.memtimingspec.entries.at("SR")),
tXSR(tCK * memSpec.memtimingspec.entries.at("XSR")),
tESCKE(tCK * memSpec.memtimingspec.entries.at("ESCKE")),
tCKE(tCK * memSpec.memtimingspec.entries.at("CKE")),
tCMDCKE(tCK * memSpec.memtimingspec.entries.at("CMDCKE")),
tRTRS(tCK * memSpec.memtimingspec.entries.at("RTRS"))
{
commandLengthInCycles[Command::ACT] = 4;
commandLengthInCycles[Command::PREPB] = 2;
@@ -105,22 +106,24 @@ MemSpecLPDDR4::MemSpecLPDDR4(const DRAMSys::Config::MemSpec &memSpec)
commandLengthInCycles[Command::SREFEN] = 2;
commandLengthInCycles[Command::SREFEX] = 2;
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBits =
static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
memorySizeBytes = deviceSizeBytes * ranksPerChannel * numberOfChannels;
std::cout << headline << std::endl;
std::cout << "Memory Configuration:" << std::endl << std::endl;
std::cout << " Memory type: " << "LPDDR4" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Memory type: "
<< "LPDDR4" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Ranks per channel: " << ranksPerChannel << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Rows per bank: " << rowsPerBank << std::endl;
std::cout << " Columns per row: " << columnsPerRow << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Devices per rank: " << devicesPerRank << std::endl;
std::cout << std::endl;
}
@@ -135,7 +138,8 @@ sc_time MemSpecLPDDR4::getRefreshIntervalPB() const
return tREFIpb;
}
sc_time MemSpecLPDDR4::getExecutionTime(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
sc_time MemSpecLPDDR4::getExecutionTime(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::PREPB)
return tRPpb + tCK;
@@ -169,12 +173,15 @@ sc_time MemSpecLPDDR4::getExecutionTime(Command command, [[maybe_unused]] const
throw;
}
TimeInterval MemSpecLPDDR4::getIntervalOnDataStrobe(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
TimeInterval
MemSpecLPDDR4::getIntervalOnDataStrobe(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::RD || command == Command::RDA)
return {tRL + tDQSCK + 3 * tCK, tRL + tDQSCK + burstDuration + 3 * tCK};
if (command == Command::WR || command == Command::WRA || command == Command::MWR || command == Command::MWRA)
if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
command == Command::MWRA)
return {tWL + tDQSS + tDQS2DQ + 3 * tCK, tWL + tDQSS + tDQS2DQ + burstDuration + 3 * tCK};
SC_REPORT_FATAL("MemSpecLPDDR4", "Method was called with invalid argument");

View File

@@ -44,11 +44,10 @@
namespace DRAMSys
{
class MemSpecLPDDR4 final : public MemSpec
{
public:
explicit MemSpecLPDDR4(const DRAMSys::Config::MemSpec &memSpec);
explicit MemSpecLPDDR4(const DRAMSys::Config::MemSpec& memSpec);
// Memspec Variables:
const sc_core::sc_time tREFI;
@@ -90,8 +89,11 @@ public:
[[nodiscard]] sc_core::sc_time getRefreshIntervalAB() const override;
[[nodiscard]] sc_core::sc_time getRefreshIntervalPB() const override;
[[nodiscard]] sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] TimeInterval
getIntervalOnDataStrobe(Command command,
const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] bool requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const override;
};

View File

@@ -46,65 +46,69 @@ using namespace tlm;
namespace DRAMSys
{
MemSpecSTTMRAM::MemSpecSTTMRAM(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::STTMRAM,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD (tCKE),
tCKESR (tCK * memSpec.memtimingspec.entries.at("CKESR")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC (tCK * memSpec.memtimingspec.entries.at("RC")),
tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tXS (tCK * memSpec.memtimingspec.entries.at("XS")),
tRP (tCK * memSpec.memtimingspec.entries.at("RP")),
tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tCCD (tCK * memSpec.memtimingspec.entries.at("CCD")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
tRRD (tCK * memSpec.memtimingspec.entries.at("RRD")),
tWTR (tCK * memSpec.memtimingspec.entries.at("WTR")),
tXPDLL (tCK * memSpec.memtimingspec.entries.at("XPDLL")),
tXSDLL (tCK * memSpec.memtimingspec.entries.at("XSDLL")),
tAL (tCK * memSpec.memtimingspec.entries.at("AL")),
tACTPDEN (tCK * memSpec.memtimingspec.entries.at("ACTPDEN")),
tPRPDEN (tCK * memSpec.memtimingspec.entries.at("PRPDEN")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS"))
MemSpecSTTMRAM::MemSpecSTTMRAM(const DRAMSys::Config::MemSpec& memSpec) :
MemSpec(memSpec,
MemoryType::STTMRAM,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tCKE(tCK * memSpec.memtimingspec.entries.at("CKE")),
tPD(tCKE),
tCKESR(tCK * memSpec.memtimingspec.entries.at("CKESR")),
tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC(tCK * memSpec.memtimingspec.entries.at("RC")),
tRCD(tCK * memSpec.memtimingspec.entries.at("RCD")),
tRL(tCK * memSpec.memtimingspec.entries.at("RL")),
tRTP(tCK * memSpec.memtimingspec.entries.at("RTP")),
tWL(tCK * memSpec.memtimingspec.entries.at("WL")),
tWR(tCK * memSpec.memtimingspec.entries.at("WR")),
tXP(tCK * memSpec.memtimingspec.entries.at("XP")),
tXS(tCK * memSpec.memtimingspec.entries.at("XS")),
tRP(tCK * memSpec.memtimingspec.entries.at("RP")),
tDQSCK(tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tCCD(tCK * memSpec.memtimingspec.entries.at("CCD")),
tFAW(tCK * memSpec.memtimingspec.entries.at("FAW")),
tRRD(tCK * memSpec.memtimingspec.entries.at("RRD")),
tWTR(tCK * memSpec.memtimingspec.entries.at("WTR")),
tXPDLL(tCK * memSpec.memtimingspec.entries.at("XPDLL")),
tXSDLL(tCK * memSpec.memtimingspec.entries.at("XSDLL")),
tAL(tCK * memSpec.memtimingspec.entries.at("AL")),
tACTPDEN(tCK * memSpec.memtimingspec.entries.at("ACTPDEN")),
tPRPDEN(tCK * memSpec.memtimingspec.entries.at("PRPDEN")),
tRTRS(tCK * memSpec.memtimingspec.entries.at("RTRS"))
{
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBits =
static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
memorySizeBytes = deviceSizeBytes * devicesPerRank * ranksPerChannel * numberOfChannels;
std::cout << headline << std::endl;
std::cout << "Memory Configuration:" << std::endl << std::endl;
std::cout << " Memory type: " << "STT-MRAM" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Memory type: "
<< "STT-MRAM" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Ranks per channel: " << ranksPerChannel << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Rows per bank: " << rowsPerBank << std::endl;
std::cout << " Columns per row: " << columnsPerRow << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Devices per rank: " << devicesPerRank << std::endl;
std::cout << std::endl;
}
// Returns the execution time for commands that have a fixed execution time
sc_time MemSpecSTTMRAM::getExecutionTime(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
sc_time MemSpecSTTMRAM::getExecutionTime(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::PREPB || command == Command::PREAB)
return tRP;
@@ -129,12 +133,14 @@ sc_time MemSpecSTTMRAM::getExecutionTime(Command command, [[maybe_unused]] const
return SC_ZERO_TIME;
}
TimeInterval MemSpecSTTMRAM::getIntervalOnDataStrobe(Command command, [[maybe_unused]] const tlm::tlm_generic_payload & payload) const
TimeInterval MemSpecSTTMRAM::getIntervalOnDataStrobe(
Command command, [[maybe_unused]] const tlm::tlm_generic_payload& payload) const
{
if (command == Command::RD || command == Command::RDA)
return {tRL, tRL + burstDuration};
if (command == Command::WR || command == Command::WRA || command == Command::MWR || command == Command::MWRA)
if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
command == Command::MWRA)
return {tWL, tWL + burstDuration};
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");

View File

@@ -47,7 +47,7 @@ namespace DRAMSys
class MemSpecSTTMRAM final : public MemSpec
{
public:
explicit MemSpecSTTMRAM(const DRAMSys::Config::MemSpec &memSpec);
explicit MemSpecSTTMRAM(const DRAMSys::Config::MemSpec& memSpec);
// Memspec Variables:
const sc_core::sc_time tCKE;
@@ -78,8 +78,11 @@ public:
// Currents and Voltages:
// TODO: to be completed
[[nodiscard]] sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] TimeInterval
getIntervalOnDataStrobe(Command command,
const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] bool requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const override;
};

View File

@@ -46,65 +46,79 @@ using namespace tlm;
namespace DRAMSys
{
MemSpecWideIO::MemSpecWideIO(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::WideIO,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")),
tCKESR (tCK * memSpec.memtimingspec.entries.at("CKESR")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC (tCK * memSpec.memtimingspec.entries.at("RC")),
tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tXSR (tCK * memSpec.memtimingspec.entries.at("XSR")),
tREFI (tCK * memSpec.memtimingspec.entries.at("REFI")),
tRFC (tCK * memSpec.memtimingspec.entries.at("RFC")),
tRP (tCK * memSpec.memtimingspec.entries.at("RP")),
tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tAC (tCK * memSpec.memtimingspec.entries.at("AC")),
tCCD_R (tCK * memSpec.memtimingspec.entries.at("CCD_R")),
tCCD_W (tCK * memSpec.memtimingspec.entries.at("CCD_W")),
tRRD (tCK * memSpec.memtimingspec.entries.at("RRD")),
tTAW (tCK * memSpec.memtimingspec.entries.at("TAW")),
tWTR (tCK * memSpec.memtimingspec.entries.at("WTR")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS")),
iDD0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd0") : 0),
iDD2N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n") : 0),
iDD3N (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n") : 0),
iDD4R (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r") : 0),
iDD4W (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w") : 0),
iDD5 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd5") : 0),
iDD6 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd6") : 0),
vDD (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd") : 0),
iDD02 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd02") : 0),
iDD2P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p0") : 0),
iDD2P02 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p02") : 0),
iDD2P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p1") : 0),
iDD2P12 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p12") : 0),
iDD2N2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n2") : 0),
iDD3P0 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p0") : 0),
iDD3P02 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p02") : 0),
iDD3P1 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p1") : 0),
iDD3P12 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p12") : 0),
iDD3N2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n2") : 0),
iDD4R2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r2") : 0),
iDD4W2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w2") : 0),
iDD52 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd52") : 0),
iDD62 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd62") : 0),
vDD2 (memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd2") : 0)
MemSpecWideIO::MemSpecWideIO(const DRAMSys::Config::MemSpec& memSpec) :
MemSpec(memSpec,
MemoryType::WideIO,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tCKE(tCK * memSpec.memtimingspec.entries.at("CKE")),
tCKESR(tCK * memSpec.memtimingspec.entries.at("CKESR")),
tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")),
tRC(tCK * memSpec.memtimingspec.entries.at("RC")),
tRCD(tCK * memSpec.memtimingspec.entries.at("RCD")),
tRL(tCK * memSpec.memtimingspec.entries.at("RL")),
tWL(tCK * memSpec.memtimingspec.entries.at("WL")),
tWR(tCK * memSpec.memtimingspec.entries.at("WR")),
tXP(tCK * memSpec.memtimingspec.entries.at("XP")),
tXSR(tCK * memSpec.memtimingspec.entries.at("XSR")),
tREFI(tCK * memSpec.memtimingspec.entries.at("REFI")),
tRFC(tCK * memSpec.memtimingspec.entries.at("RFC")),
tRP(tCK * memSpec.memtimingspec.entries.at("RP")),
tDQSCK(tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tAC(tCK * memSpec.memtimingspec.entries.at("AC")),
tCCD_R(tCK * memSpec.memtimingspec.entries.at("CCD_R")),
tCCD_W(tCK * memSpec.memtimingspec.entries.at("CCD_W")),
tRRD(tCK * memSpec.memtimingspec.entries.at("RRD")),
tTAW(tCK * memSpec.memtimingspec.entries.at("TAW")),
tWTR(tCK * memSpec.memtimingspec.entries.at("WTR")),
tRTRS(tCK * memSpec.memtimingspec.entries.at("RTRS")),
iDD0(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd0") : 0),
iDD2N(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n") : 0),
iDD3N(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n") : 0),
iDD4R(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r") : 0),
iDD4W(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w") : 0),
iDD5(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd5") : 0),
iDD6(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd6") : 0),
vDD(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd") : 0),
iDD02(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd02") : 0),
iDD2P0(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p0")
: 0),
iDD2P02(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p02")
: 0),
iDD2P1(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p1")
: 0),
iDD2P12(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2p12")
: 0),
iDD2N2(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd2n2")
: 0),
iDD3P0(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p0")
: 0),
iDD3P02(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p02")
: 0),
iDD3P1(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p1")
: 0),
iDD3P12(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3p12")
: 0),
iDD3N2(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd3n2")
: 0),
iDD4R2(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4r2")
: 0),
iDD4W2(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd4w2")
: 0),
iDD52(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd52") : 0),
iDD62(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("idd62") : 0),
vDD2(memSpec.mempowerspec.has_value() ? memSpec.mempowerspec.value().entries.at("vdd2") : 0)
{
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBits =
static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
memorySizeBytes = deviceSizeBytes * ranksPerChannel * numberOfChannels;
@@ -113,16 +127,17 @@ MemSpecWideIO::MemSpecWideIO(const DRAMSys::Config::MemSpec &memSpec)
std::cout << headline << std::endl;
std::cout << "Memory Configuration:" << std::endl << std::endl;
std::cout << " Memory type: " << "Wide I/O" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Memory type: "
<< "Wide I/O" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Ranks per channel: " << ranksPerChannel << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Rows per bank: " << rowsPerBank << std::endl;
std::cout << " Columns per row: " << columnsPerRow << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Devices per rank: " << devicesPerRank << std::endl;
std::cout << std::endl;
}
@@ -133,7 +148,8 @@ sc_time MemSpecWideIO::getRefreshIntervalAB() const
}
// Returns the execution time for commands that have a fixed execution time
sc_time MemSpecWideIO::getExecutionTime(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
sc_time MemSpecWideIO::getExecutionTime(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::PREPB || command == Command::PREAB)
return tRP;
@@ -161,12 +177,15 @@ sc_time MemSpecWideIO::getExecutionTime(Command command, [[maybe_unused]] const
throw;
}
TimeInterval MemSpecWideIO::getIntervalOnDataStrobe(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
TimeInterval
MemSpecWideIO::getIntervalOnDataStrobe(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::RD || command == Command::RDA)
return {tRL + tAC, tRL + tAC + burstDuration};
if (command == Command::WR || command == Command::WRA || command == Command::MWR || command == Command::MWRA)
if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
command == Command::MWRA)
return {tWL, tWL + burstDuration};
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");

View File

@@ -47,7 +47,7 @@ namespace DRAMSys
class MemSpecWideIO final : public MemSpec
{
public:
explicit MemSpecWideIO(const DRAMSys::Config::MemSpec &memSpec);
explicit MemSpecWideIO(const DRAMSys::Config::MemSpec& memSpec);
// Memspec Variables:
const sc_core::sc_time tCKE;
@@ -100,8 +100,11 @@ public:
[[nodiscard]] sc_core::sc_time getRefreshIntervalAB() const override;
[[nodiscard]] sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] TimeInterval
getIntervalOnDataStrobe(Command command,
const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] bool requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const override;
};

View File

@@ -46,62 +46,65 @@ using namespace tlm;
namespace DRAMSys
{
MemSpecWideIO2::MemSpecWideIO2(const DRAMSys::Config::MemSpec &memSpec)
: MemSpec(memSpec, MemoryType::WideIO2,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks")
* memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tDQSCK (tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tDQSS (tCK * memSpec.memtimingspec.entries.at("DQSS")),
tCKE (tCK * memSpec.memtimingspec.entries.at("CKE")),
tRL (tCK * memSpec.memtimingspec.entries.at("RL")),
tWL (tCK * memSpec.memtimingspec.entries.at("WL")),
tRCpb (tCK * memSpec.memtimingspec.entries.at("RCPB")),
tRCab (tCK * memSpec.memtimingspec.entries.at("RCAB")),
tCKESR (tCK * memSpec.memtimingspec.entries.at("CKESR")),
tXSR (tCK * memSpec.memtimingspec.entries.at("XSR")),
tXP (tCK * memSpec.memtimingspec.entries.at("XP")),
tCCD (tCK * memSpec.memtimingspec.entries.at("CCD")),
tRTP (tCK * memSpec.memtimingspec.entries.at("RTP")),
tRCD (tCK * memSpec.memtimingspec.entries.at("RCD")),
tRPpb (tCK * memSpec.memtimingspec.entries.at("RPPB")),
tRPab (tCK * memSpec.memtimingspec.entries.at("RPAB")),
tRAS (tCK * memSpec.memtimingspec.entries.at("RAS")),
tWR (tCK * memSpec.memtimingspec.entries.at("WR")),
tWTR (tCK * memSpec.memtimingspec.entries.at("WTR")),
tRRD (tCK * memSpec.memtimingspec.entries.at("RRD")),
tFAW (tCK * memSpec.memtimingspec.entries.at("FAW")),
tREFI (tCK * static_cast<unsigned>(memSpec.memtimingspec.entries.at("REFI")
* memSpec.memtimingspec.entries.at("REFM"))),
tREFIpb (tCK * static_cast<unsigned>(memSpec.memtimingspec.entries.at("REFIPB")
* memSpec.memtimingspec.entries.at("REFM"))),
tRFCab (tCK * memSpec.memtimingspec.entries.at("RFCAB")),
tRFCpb (tCK * memSpec.memtimingspec.entries.at("RFCPB")),
tRTRS (tCK * memSpec.memtimingspec.entries.at("RTRS"))
MemSpecWideIO2::MemSpecWideIO2(const DRAMSys::Config::MemSpec& memSpec) :
MemSpec(memSpec,
MemoryType::WideIO2,
memSpec.memarchitecturespec.entries.at("nbrOfChannels"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
1,
memSpec.memarchitecturespec.entries.at("nbrOfBanks"),
memSpec.memarchitecturespec.entries.at("nbrOfBanks") *
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfRanks"),
memSpec.memarchitecturespec.entries.at("nbrOfDevices")),
tDQSCK(tCK * memSpec.memtimingspec.entries.at("DQSCK")),
tDQSS(tCK * memSpec.memtimingspec.entries.at("DQSS")),
tCKE(tCK * memSpec.memtimingspec.entries.at("CKE")),
tRL(tCK * memSpec.memtimingspec.entries.at("RL")),
tWL(tCK * memSpec.memtimingspec.entries.at("WL")),
tRCpb(tCK * memSpec.memtimingspec.entries.at("RCPB")),
tRCab(tCK * memSpec.memtimingspec.entries.at("RCAB")),
tCKESR(tCK * memSpec.memtimingspec.entries.at("CKESR")),
tXSR(tCK * memSpec.memtimingspec.entries.at("XSR")),
tXP(tCK * memSpec.memtimingspec.entries.at("XP")),
tCCD(tCK * memSpec.memtimingspec.entries.at("CCD")),
tRTP(tCK * memSpec.memtimingspec.entries.at("RTP")),
tRCD(tCK * memSpec.memtimingspec.entries.at("RCD")),
tRPpb(tCK * memSpec.memtimingspec.entries.at("RPPB")),
tRPab(tCK * memSpec.memtimingspec.entries.at("RPAB")),
tRAS(tCK * memSpec.memtimingspec.entries.at("RAS")),
tWR(tCK * memSpec.memtimingspec.entries.at("WR")),
tWTR(tCK * memSpec.memtimingspec.entries.at("WTR")),
tRRD(tCK * memSpec.memtimingspec.entries.at("RRD")),
tFAW(tCK * memSpec.memtimingspec.entries.at("FAW")),
tREFI(tCK * static_cast<unsigned>(memSpec.memtimingspec.entries.at("REFI") *
memSpec.memtimingspec.entries.at("REFM"))),
tREFIpb(tCK * static_cast<unsigned>(memSpec.memtimingspec.entries.at("REFIPB") *
memSpec.memtimingspec.entries.at("REFM"))),
tRFCab(tCK * memSpec.memtimingspec.entries.at("RFCAB")),
tRFCpb(tCK * memSpec.memtimingspec.entries.at("RFCPB")),
tRTRS(tCK * memSpec.memtimingspec.entries.at("RTRS"))
{
uint64_t deviceSizeBits = static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBits =
static_cast<uint64_t>(banksPerRank) * rowsPerBank * columnsPerRow * bitWidth;
uint64_t deviceSizeBytes = deviceSizeBits / 8;
memorySizeBytes = deviceSizeBytes * ranksPerChannel * numberOfChannels;
std::cout << headline << std::endl;
std::cout << "Memory Configuration:" << std::endl << std::endl;
std::cout << " Memory type: " << "Wide I/O 2" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Memory type: "
<< "Wide I/O 2" << std::endl;
std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl;
std::cout << " Channels: " << numberOfChannels << std::endl;
std::cout << " Ranks per channel: " << ranksPerChannel << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Banks per rank: " << banksPerRank << std::endl;
std::cout << " Rows per bank: " << rowsPerBank << std::endl;
std::cout << " Columns per row: " << columnsPerRow << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Device width in bits: " << bitWidth << std::endl;
std::cout << " Device size in bits: " << deviceSizeBits << std::endl;
std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl;
std::cout << " Devices per rank: " << devicesPerRank << std::endl;
std::cout << std::endl;
}
@@ -117,7 +120,8 @@ sc_time MemSpecWideIO2::getRefreshIntervalPB() const
}
// Returns the execution time for commands that have a fixed execution time
sc_time MemSpecWideIO2::getExecutionTime(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
sc_time MemSpecWideIO2::getExecutionTime(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::PREPB)
return tRPpb;
@@ -151,12 +155,15 @@ sc_time MemSpecWideIO2::getExecutionTime(Command command, [[maybe_unused]] const
throw;
}
TimeInterval MemSpecWideIO2::getIntervalOnDataStrobe(Command command, [[maybe_unused]] const tlm_generic_payload & payload) const
TimeInterval
MemSpecWideIO2::getIntervalOnDataStrobe(Command command,
[[maybe_unused]] const tlm_generic_payload& payload) const
{
if (command == Command::RD || command == Command::RDA)
return {tRL + tDQSCK, tRL + tDQSCK + burstDuration};
if (command == Command::WR || command == Command::WRA || command == Command::MWR || command == Command::MWRA)
if (command == Command::WR || command == Command::WRA || command == Command::MWR ||
command == Command::MWRA)
return {tWL + tDQSS, tWL + tDQSS + burstDuration};
SC_REPORT_FATAL("MemSpec", "Method was called with invalid argument");

View File

@@ -47,7 +47,7 @@ namespace DRAMSys
class MemSpecWideIO2 final : public MemSpec
{
public:
explicit MemSpecWideIO2(const DRAMSys::Config::MemSpec &memSpec);
explicit MemSpecWideIO2(const DRAMSys::Config::MemSpec& memSpec);
// Memspec Variables:
const sc_core::sc_time tDQSCK;
@@ -82,8 +82,11 @@ public:
[[nodiscard]] sc_core::sc_time getRefreshIntervalAB() const override;
[[nodiscard]] sc_core::sc_time getRefreshIntervalPB() const override;
[[nodiscard]] sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] TimeInterval getIntervalOnDataStrobe(Command command, const tlm::tlm_generic_payload &payload) const override;
[[nodiscard]] sc_core::sc_time
getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] TimeInterval
getIntervalOnDataStrobe(Command command,
const tlm::tlm_generic_payload& payload) const override;
[[nodiscard]] bool requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const override;
};

View File

@@ -69,24 +69,35 @@ void BankMachine::update(Command command)
keepTrans = true;
refreshManagementCounter++;
break;
case Command::PREPB: case Command::PRESB: case Command::PREAB:
case Command::PREPB:
case Command::PRESB:
case Command::PREAB:
state = State::Precharged;
keepTrans = false;
break;
case Command::RD: case Command::WR: case Command::MWR:
case Command::RD:
case Command::WR:
case Command::MWR:
currentPayload = nullptr;
keepTrans = false;
break;
case Command::RDA: case Command::WRA: case Command::MWRA:
case Command::RDA:
case Command::WRA:
case Command::MWRA:
state = State::Precharged;
currentPayload = nullptr;
keepTrans = false;
break;
case Command::PDEA: case Command::PDEP: case Command::SREFEN:
case Command::PDEA:
case Command::PDEP:
case Command::SREFEN:
assert(!keepTrans);
sleeping = true;
break;
case Command::REFPB: case Command::REFP2B: case Command::REFSB: case Command::REFAB:
case Command::REFPB:
case Command::REFP2B:
case Command::REFSB:
case Command::REFAB:
sleeping = false;
blocked = false;
@@ -98,7 +109,10 @@ void BankMachine::update(Command command)
refreshManagementCounter = 0;
}
break;
case Command::RFMPB: case Command::RFMP2B: case Command::RFMSB: case Command::RFMAB:
case Command::RFMPB:
case Command::RFMP2B:
case Command::RFMSB:
case Command::RFMAB:
assert(!keepTrans);
sleeping = false;
blocked = false;
@@ -111,7 +125,8 @@ void BankMachine::update(Command command)
refreshManagementCounter = 0;
}
break;
case Command::PDXA: case Command::PDXP:
case Command::PDXA:
case Command::PDXP:
assert(!keepTrans);
sleeping = false;
break;
@@ -166,8 +181,12 @@ bool BankMachine::isPrecharged() const
return state == State::Precharged;
}
BankMachineOpen::BankMachineOpen(const Configuration& config, const SchedulerIF& scheduler, Bank bank)
: BankMachine(config, scheduler, bank) {}
BankMachineOpen::BankMachineOpen(const Configuration& config,
const SchedulerIF& scheduler,
Bank bank) :
BankMachine(config, scheduler, bank)
{
}
void BankMachineOpen::evaluate()
{
@@ -175,7 +194,7 @@ void BankMachineOpen::evaluate()
if (!(sleeping || blocked))
{
tlm_generic_payload *newPayload = scheduler.getNextRequest(*this);
tlm_generic_payload* newPayload = scheduler.getNextRequest(*this);
if (newPayload == nullptr)
return;
@@ -201,7 +220,8 @@ void BankMachineOpen::evaluate()
nextCommand = Command::RD;
else
{
nextCommand = memSpec.requiresMaskedWrite(*currentPayload) ? Command::MWR : Command::WR;
nextCommand =
memSpec.requiresMaskedWrite(*currentPayload) ? Command::MWR : Command::WR;
}
}
else // row miss
@@ -210,8 +230,12 @@ void BankMachineOpen::evaluate()
}
}
BankMachineClosed::BankMachineClosed(const Configuration& config, const SchedulerIF& scheduler, Bank bank)
: BankMachine(config, scheduler, bank) {}
BankMachineClosed::BankMachineClosed(const Configuration& config,
const SchedulerIF& scheduler,
Bank bank) :
BankMachine(config, scheduler, bank)
{
}
void BankMachineClosed::evaluate()
{
@@ -219,7 +243,7 @@ void BankMachineClosed::evaluate()
if (!(sleeping || blocked))
{
tlm_generic_payload *newPayload = scheduler.getNextRequest(*this);
tlm_generic_payload* newPayload = scheduler.getNextRequest(*this);
if (newPayload == nullptr)
return;
@@ -243,14 +267,19 @@ void BankMachineClosed::evaluate()
nextCommand = Command::RDA;
else
{
nextCommand = memSpec.requiresMaskedWrite(*currentPayload) ? Command::MWRA : Command::WRA;
nextCommand =
memSpec.requiresMaskedWrite(*currentPayload) ? Command::MWRA : Command::WRA;
}
}
}
}
BankMachineOpenAdaptive::BankMachineOpenAdaptive(const Configuration& config, const SchedulerIF& scheduler, Bank bank)
: BankMachine(config, scheduler, bank) {}
BankMachineOpenAdaptive::BankMachineOpenAdaptive(const Configuration& config,
const SchedulerIF& scheduler,
Bank bank) :
BankMachine(config, scheduler, bank)
{
}
void BankMachineOpenAdaptive::evaluate()
{
@@ -258,7 +287,7 @@ void BankMachineOpenAdaptive::evaluate()
if (!(sleeping || blocked))
{
tlm_generic_payload *newPayload = scheduler.getNextRequest(*this);
tlm_generic_payload* newPayload = scheduler.getNextRequest(*this);
if (newPayload == nullptr)
return;
@@ -287,7 +316,8 @@ void BankMachineOpenAdaptive::evaluate()
nextCommand = Command::RDA;
else
{
nextCommand = memSpec.requiresMaskedWrite(*currentPayload) ? Command::MWRA : Command::WRA;
nextCommand = memSpec.requiresMaskedWrite(*currentPayload) ? Command::MWRA
: Command::WRA;
}
}
else
@@ -297,7 +327,8 @@ void BankMachineOpenAdaptive::evaluate()
nextCommand = Command::RD;
else
{
nextCommand = memSpec.requiresMaskedWrite(*currentPayload) ? Command::MWR : Command::WR;
nextCommand = memSpec.requiresMaskedWrite(*currentPayload) ? Command::MWR
: Command::WR;
}
}
}
@@ -307,9 +338,12 @@ void BankMachineOpenAdaptive::evaluate()
}
}
BankMachineClosedAdaptive::BankMachineClosedAdaptive(const Configuration& config, const SchedulerIF& scheduler,
Bank bank)
: BankMachine(config, scheduler, bank) {}
BankMachineClosedAdaptive::BankMachineClosedAdaptive(const Configuration& config,
const SchedulerIF& scheduler,
Bank bank) :
BankMachine(config, scheduler, bank)
{
}
void BankMachineClosedAdaptive::evaluate()
{
@@ -317,7 +351,7 @@ void BankMachineClosedAdaptive::evaluate()
if (!(sleeping || blocked))
{
tlm_generic_payload *newPayload = scheduler.getNextRequest(*this);
tlm_generic_payload* newPayload = scheduler.getNextRequest(*this);
if (newPayload == nullptr)
return;
@@ -345,7 +379,8 @@ void BankMachineClosedAdaptive::evaluate()
nextCommand = Command::RD;
else
{
nextCommand = memSpec.requiresMaskedWrite(*currentPayload) ? Command::MWR : Command::WR;
nextCommand = memSpec.requiresMaskedWrite(*currentPayload) ? Command::MWR
: Command::WR;
}
}
else
@@ -355,7 +390,8 @@ void BankMachineClosedAdaptive::evaluate()
nextCommand = Command::RDA;
else
{
nextCommand = memSpec.requiresMaskedWrite(*currentPayload) ? Command::MWRA : Command::WRA;
nextCommand = memSpec.requiresMaskedWrite(*currentPayload) ? Command::MWRA
: Command::WRA;
}
}
}

View File

@@ -35,13 +35,13 @@
#ifndef BANKMACHINE_H
#define BANKMACHINE_H
#include "DRAMSys/controller/ManagerIF.h"
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
#include "DRAMSys/controller/checker/CheckerIF.h"
#include "DRAMSys/controller/Command.h"
#include "DRAMSys/common/dramExtensions.h"
#include "DRAMSys/configuration/memspec/MemSpec.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/checker/CheckerIF.h"
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
#include <systemc>
#include <tlm>
@@ -66,7 +66,11 @@ public:
[[nodiscard]] uint64_t getRefreshManagementCounter() const;
protected:
enum class State {Precharged, Activated} state = State::Precharged;
enum class State
{
Precharged,
Activated
} state = State::Precharged;
BankMachine(const Configuration& config, const SchedulerIF& scheduler, Bank bank);
const MemSpec& memSpec;
tlm::tlm_generic_payload* currentPayload = nullptr;

View File

@@ -71,77 +71,78 @@ bool isFixedCommandPhase(tlm::tlm_phase phase)
bool isRefreshCommandPhase(tlm::tlm_phase phase)
{
return (phase == BEGIN_REFPB || phase == BEGIN_REFP2B || phase == BEGIN_REFSB || phase == BEGIN_REFAB
|| phase == BEGIN_RFMPB || phase == BEGIN_RFMP2B || phase == BEGIN_RFMSB || phase == BEGIN_RFMAB);
return (phase == BEGIN_REFPB || phase == BEGIN_REFP2B || phase == BEGIN_REFSB ||
phase == BEGIN_REFAB || phase == BEGIN_RFMPB || phase == BEGIN_RFMP2B ||
phase == BEGIN_RFMSB || phase == BEGIN_RFMAB);
}
Command::Command(Command::Type type) : type(type) {}
Command::Command(Command::Type type) : type(type)
{
}
Command::Command(tlm_phase phase)
{
assert(phase >= BEGIN_NOP && phase <= END_SREF);
static constexpr std::array<Command::Type, Command::Type::END_ENUM> commandOfPhase =
{
Command::NOP, // 0
Command::RD, // 1
Command::WR, // 2
Command::MWR, // 3
Command::RDA, // 4
Command::WRA, // 5
Command::MWRA, // 6
Command::ACT, // 7
Command::PREPB, // 8
Command::REFPB, // 9
Command::RFMPB, // 10
Command::REFP2B, // 11
Command::RFMP2B, // 12
Command::PRESB, // 13
Command::REFSB, // 14
Command::RFMSB, // 15
Command::PREAB, // 16
Command::REFAB, // 17
Command::RFMAB, // 18
Command::PDEA, // 19
Command::PDEP, // 20
Command::SREFEN, // 21
Command::PDXA, // 22
Command::PDXP, // 23
Command::SREFEX // 24
};
static constexpr std::array<Command::Type, Command::Type::END_ENUM> commandOfPhase = {
Command::NOP, // 0
Command::RD, // 1
Command::WR, // 2
Command::MWR, // 3
Command::RDA, // 4
Command::WRA, // 5
Command::MWRA, // 6
Command::ACT, // 7
Command::PREPB, // 8
Command::REFPB, // 9
Command::RFMPB, // 10
Command::REFP2B, // 11
Command::RFMP2B, // 12
Command::PRESB, // 13
Command::REFSB, // 14
Command::RFMSB, // 15
Command::PREAB, // 16
Command::REFAB, // 17
Command::RFMAB, // 18
Command::PDEA, // 19
Command::PDEP, // 20
Command::SREFEN, // 21
Command::PDXA, // 22
Command::PDXP, // 23
Command::SREFEX // 24
};
type = commandOfPhase[phase - BEGIN_NOP];
}
std::string Command::toString() const
{
assert(type >= Command::NOP && type <= Command::SREFEX);
static std::array<std::string, Command::Type::END_ENUM> stringOfCommand =
{
"NOP", // 0
"RD", // 1
"WR", // 2
"MWR", // 3
"RDA", // 4
"WRA", // 5
"MWRA", // 6
"ACT", // 7
"PREPB", // 8
"REFPB", // 9
"RFMPB", // 10
"REFP2B", // 11
"RFMP2B", // 12
"PRESB", // 13
"REFSB", // 14
"RFMSB", // 15
"PREAB", // 16
"REFAB", // 17
"RFMAB", // 18
"PDEA", // 19
"PDEP", // 20
"SREFEN", // 21
"PDXA", // 22
"PDXP", // 23
"SREFEX" // 24
};
static std::array<std::string, Command::Type::END_ENUM> stringOfCommand = {
"NOP", // 0
"RD", // 1
"WR", // 2
"MWR", // 3
"RDA", // 4
"WRA", // 5
"MWRA", // 6
"ACT", // 7
"PREPB", // 8
"REFPB", // 9
"RFMPB", // 10
"REFP2B", // 11
"RFMP2B", // 12
"PRESB", // 13
"REFSB", // 14
"RFMSB", // 15
"PREAB", // 16
"REFAB", // 17
"RFMAB", // 18
"PDEA", // 19
"PDEP", // 20
"SREFEN", // 21
"PDXA", // 22
"PDXP", // 23
"SREFEX" // 24
};
return stringOfCommand[type];
}
@@ -153,34 +154,33 @@ unsigned Command::numberOfCommands()
tlm_phase Command::toPhase() const
{
assert(type >= Command::NOP && type <= Command::SREFEX);
static std::array<tlm_phase, Command::Type::END_ENUM> phaseOfCommand =
{
BEGIN_NOP, // 0
BEGIN_RD, // 1
BEGIN_WR, // 2
BEGIN_MWR, // 3
BEGIN_RDA, // 4
BEGIN_WRA, // 5
BEGIN_MWRA, // 6
BEGIN_ACT, // 7
BEGIN_PREPB, // 8
BEGIN_REFPB, // 9
BEGIN_RFMPB, // 10
BEGIN_REFP2B, // 11
BEGIN_RFMP2B, // 12
BEGIN_PRESB, // 13
BEGIN_REFSB, // 14
BEGIN_RFMSB, // 15
BEGIN_PREAB, // 16
BEGIN_REFAB, // 17
BEGIN_RFMAB, // 18
BEGIN_PDNA, // 19
BEGIN_PDNP, // 20
BEGIN_SREF, // 21
END_PDNA, // 22
END_PDNP, // 23
END_SREF // 24
};
static std::array<tlm_phase, Command::Type::END_ENUM> phaseOfCommand = {
BEGIN_NOP, // 0
BEGIN_RD, // 1
BEGIN_WR, // 2
BEGIN_MWR, // 3
BEGIN_RDA, // 4
BEGIN_WRA, // 5
BEGIN_MWRA, // 6
BEGIN_ACT, // 7
BEGIN_PREPB, // 8
BEGIN_REFPB, // 9
BEGIN_RFMPB, // 10
BEGIN_REFP2B, // 11
BEGIN_RFMP2B, // 12
BEGIN_PRESB, // 13
BEGIN_REFSB, // 14
BEGIN_RFMSB, // 15
BEGIN_PREAB, // 16
BEGIN_REFAB, // 17
BEGIN_RFMAB, // 18
BEGIN_PDNA, // 19
BEGIN_PDNP, // 20
BEGIN_SREF, // 21
END_PDNA, // 22
END_PDNP, // 23
END_SREF // 24
};
return phaseOfCommand[type];
}
@@ -189,34 +189,33 @@ MemCommand::cmds phaseToDRAMPowerCommand(tlm_phase phase)
{
// TODO: add correct phases when DRAMPower supports DDR5 same bank refresh
assert(phase >= BEGIN_NOP && phase <= END_SREF);
static std::array<MemCommand::cmds, Command::Type::END_ENUM> phaseOfCommand =
{
MemCommand::NOP, // 0
MemCommand::RD, // 1
MemCommand::WR, // 2
MemCommand::NOP, // 3
MemCommand::RDA, // 4
MemCommand::WRA, // 5
MemCommand::NOP, // 6
MemCommand::ACT, // 7
MemCommand::PRE, // 8, PREPB
MemCommand::REFB, // 9, REFPB
MemCommand::NOP, // 10, RFMPB
MemCommand::NOP, // 11, REFP2B
MemCommand::NOP, // 12, RFMP2B
MemCommand::NOP, // 13, PRESB
MemCommand::NOP, // 14, REFSB
MemCommand::NOP, // 15, RFMSB
MemCommand::PREA, // 16, PREAB
MemCommand::REF, // 17, REFAB
MemCommand::NOP, // 18, RFMAB
MemCommand::PDN_S_ACT, // 19
MemCommand::PDN_S_PRE, // 20
MemCommand::SREN, // 21
MemCommand::PUP_ACT, // 22
MemCommand::PUP_PRE, // 23
MemCommand::SREX // 24
};
static std::array<MemCommand::cmds, Command::Type::END_ENUM> phaseOfCommand = {
MemCommand::NOP, // 0
MemCommand::RD, // 1
MemCommand::WR, // 2
MemCommand::NOP, // 3
MemCommand::RDA, // 4
MemCommand::WRA, // 5
MemCommand::NOP, // 6
MemCommand::ACT, // 7
MemCommand::PRE, // 8, PREPB
MemCommand::REFB, // 9, REFPB
MemCommand::NOP, // 10, RFMPB
MemCommand::NOP, // 11, REFP2B
MemCommand::NOP, // 12, RFMP2B
MemCommand::NOP, // 13, PRESB
MemCommand::NOP, // 14, REFSB
MemCommand::NOP, // 15, RFMSB
MemCommand::PREA, // 16, PREAB
MemCommand::REF, // 17, REFAB
MemCommand::NOP, // 18, RFMAB
MemCommand::PDN_S_ACT, // 19
MemCommand::PDN_S_PRE, // 20
MemCommand::SREN, // 21
MemCommand::PUP_ACT, // 22
MemCommand::PUP_PRE, // 23
MemCommand::SREX // 24
};
return phaseOfCommand[phase - BEGIN_NOP];
}
#endif

View File

@@ -42,10 +42,10 @@
#endif
#include <string>
#include <vector>
#include <tuple>
#include <systemc>
#include <tlm>
#include <tuple>
#include <vector>
namespace DRAMSys
{
@@ -77,13 +77,13 @@ DECLARE_EXTENDED_PHASE(BEGIN_PREAB); // 21
DECLARE_EXTENDED_PHASE(BEGIN_REFAB); // 22
DECLARE_EXTENDED_PHASE(BEGIN_RFMAB); // 23
DECLARE_EXTENDED_PHASE(BEGIN_PDNA); // 24
DECLARE_EXTENDED_PHASE(BEGIN_PDNP); // 25
DECLARE_EXTENDED_PHASE(BEGIN_SREF); // 26
DECLARE_EXTENDED_PHASE(BEGIN_PDNA); // 24
DECLARE_EXTENDED_PHASE(BEGIN_PDNP); // 25
DECLARE_EXTENDED_PHASE(BEGIN_SREF); // 26
DECLARE_EXTENDED_PHASE(END_PDNA); // 27
DECLARE_EXTENDED_PHASE(END_PDNP); // 28
DECLARE_EXTENDED_PHASE(END_SREF); // 29
DECLARE_EXTENDED_PHASE(END_PDNA); // 27
DECLARE_EXTENDED_PHASE(END_PDNP); // 28
DECLARE_EXTENDED_PHASE(END_SREF); // 29
#ifdef DRAMPOWER
DRAMPower::MemCommand::cmds phaseToDRAMPowerCommand(tlm::tlm_phase phase);
@@ -146,10 +146,7 @@ public:
[[nodiscard]] bool isCasCommand() const;
[[nodiscard]] bool isRasCommand() const;
constexpr operator uint8_t() const
{
return type;
}
constexpr operator uint8_t() const { return type; }
};
struct CommandTuple

View File

@@ -34,34 +34,34 @@
#include "Controller.h"
#include "DRAMSys/common/dramExtensions.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/controller/checker/CheckerDDR3.h"
#include "DRAMSys/controller/checker/CheckerDDR4.h"
#include "DRAMSys/controller/checker/CheckerWideIO.h"
#include "DRAMSys/controller/checker/CheckerLPDDR4.h"
#include "DRAMSys/controller/checker/CheckerWideIO2.h"
#include "DRAMSys/controller/checker/CheckerHBM2.h"
#include "DRAMSys/controller/checker/CheckerGDDR5.h"
#include "DRAMSys/controller/checker/CheckerGDDR5X.h"
#include "DRAMSys/controller/checker/CheckerGDDR6.h"
#include "DRAMSys/controller/checker/CheckerHBM2.h"
#include "DRAMSys/controller/checker/CheckerLPDDR4.h"
#include "DRAMSys/controller/checker/CheckerSTTMRAM.h"
#include "DRAMSys/controller/checker/CheckerWideIO.h"
#include "DRAMSys/controller/checker/CheckerWideIO2.h"
#include "DRAMSys/controller/cmdmux/CmdMuxOldest.h"
#include "DRAMSys/controller/cmdmux/CmdMuxStrict.h"
#include "DRAMSys/controller/powerdown/PowerDownManagerDummy.h"
#include "DRAMSys/controller/powerdown/PowerDownManagerStaggered.h"
#include "DRAMSys/controller/refresh/RefreshManagerAllBank.h"
#include "DRAMSys/controller/refresh/RefreshManagerDummy.h"
#include "DRAMSys/controller/refresh/RefreshManagerPer2Bank.h"
#include "DRAMSys/controller/refresh/RefreshManagerPerBank.h"
#include "DRAMSys/controller/refresh/RefreshManagerSameBank.h"
#include "DRAMSys/controller/respqueue/RespQueueFifo.h"
#include "DRAMSys/controller/respqueue/RespQueueReorder.h"
#include "DRAMSys/controller/scheduler/SchedulerFifo.h"
#include "DRAMSys/controller/scheduler/SchedulerFrFcfs.h"
#include "DRAMSys/controller/scheduler/SchedulerFrFcfsGrp.h"
#include "DRAMSys/controller/scheduler/SchedulerGrpFrFcfs.h"
#include "DRAMSys/controller/scheduler/SchedulerGrpFrFcfsWm.h"
#include "DRAMSys/controller/cmdmux/CmdMuxStrict.h"
#include "DRAMSys/controller/cmdmux/CmdMuxOldest.h"
#include "DRAMSys/controller/respqueue/RespQueueFifo.h"
#include "DRAMSys/controller/respqueue/RespQueueReorder.h"
#include "DRAMSys/controller/refresh/RefreshManagerDummy.h"
#include "DRAMSys/controller/refresh/RefreshManagerAllBank.h"
#include "DRAMSys/controller/refresh/RefreshManagerPerBank.h"
#include "DRAMSys/controller/refresh/RefreshManagerPer2Bank.h"
#include "DRAMSys/controller/refresh/RefreshManagerSameBank.h"
#include "DRAMSys/controller/powerdown/PowerDownManagerStaggered.h"
#include "DRAMSys/controller/powerdown/PowerDownManagerDummy.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/common/dramExtensions.h"
#ifdef DDR5_SIM
#include "DRAMSys/controller/checker/CheckerDDR5.h"
@@ -79,11 +79,17 @@ using namespace tlm;
namespace DRAMSys
{
Controller::Controller(const sc_module_name& name, const Configuration& config, const AddressDecoder& addressDecoder) :
ControllerIF(name, config), thinkDelayFw(config.thinkDelayFw),
thinkDelayBw(config.thinkDelayBw), phyDelayFw(config.phyDelayFw),
phyDelayBw(config.phyDelayBw), blockingReadDelay(config.blockingReadDelay),
blockingWriteDelay(config.blockingWriteDelay), addressDecoder(addressDecoder),
Controller::Controller(const sc_module_name& name,
const Configuration& config,
const AddressDecoder& addressDecoder) :
ControllerIF(name, config),
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)
{
@@ -129,7 +135,6 @@ Controller::Controller(const sc_module_name& name, const Configuration& config,
checker = std::make_unique<CheckerHBM3>(config);
#endif
// instantiate scheduler and command mux
if (config.scheduler == Configuration::Scheduler::Fifo)
scheduler = std::make_unique<SchedulerFifo>(config);
@@ -166,35 +171,35 @@ Controller::Controller(const sc_module_name& name, const Configuration& config,
if (config.pagePolicy == Configuration::PagePolicy::Open)
{
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
bankMachines.push_back(std::make_unique<BankMachineOpen>
(config, *scheduler, Bank(bankID)));
bankMachines.push_back(
std::make_unique<BankMachineOpen>(config, *scheduler, Bank(bankID)));
}
else if (config.pagePolicy == Configuration::PagePolicy::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, *scheduler, Bank(bankID)));
}
else if (config.pagePolicy == Configuration::PagePolicy::Closed)
{
for (unsigned bankID = 0; bankID < memSpec.banksPerChannel; bankID++)
bankMachines.push_back(std::make_unique<BankMachineClosed>
(config, *scheduler, Bank(bankID)));
bankMachines.push_back(
std::make_unique<BankMachineClosed>(config, *scheduler, Bank(bankID)));
}
else if (config.pagePolicy == Configuration::PagePolicy::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, *scheduler, Bank(bankID)));
}
bankMachinesOnRank = ControllerVector<Rank, ControllerVector<Bank, BankMachine*>>(memSpec.ranksPerChannel,
ControllerVector<Bank, BankMachine*>(memSpec.banksPerRank));
bankMachinesOnRank = ControllerVector<Rank, ControllerVector<Bank, BankMachine*>>(
memSpec.ranksPerChannel, ControllerVector<Bank, BankMachine*>(memSpec.banksPerRank));
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
{
for (unsigned bankID = 0; bankID < memSpec.banksPerRank; bankID++)
bankMachinesOnRank[Rank(rankID)][Bank(bankID)]
= bankMachines[Bank(rankID * memSpec.banksPerRank + bankID)].get();
bankMachinesOnRank[Rank(rankID)][Bank(bankID)] =
bankMachines[Bank(rankID * memSpec.banksPerRank + bankID)].get();
}
// instantiate power-down managers (one per rank)
@@ -222,16 +227,22 @@ Controller::Controller(const sc_module_name& name, const Configuration& config,
{
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
{
refreshManagers.push_back(std::make_unique<RefreshManagerAllBank>
(config, bankMachinesOnRank[Rank(rankID)], *powerDownManagers[Rank(rankID)], Rank(rankID)));
refreshManagers.push_back(
std::make_unique<RefreshManagerAllBank>(config,
bankMachinesOnRank[Rank(rankID)],
*powerDownManagers[Rank(rankID)],
Rank(rankID)));
}
}
else if (config.refreshPolicy == Configuration::RefreshPolicy::SameBank)
{
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
{
refreshManagers.push_back(std::make_unique<RefreshManagerSameBank>
(config, bankMachinesOnRank[Rank(rankID)], *powerDownManagers[Rank(rankID)], Rank(rankID)));
refreshManagers.push_back(
std::make_unique<RefreshManagerSameBank>(config,
bankMachinesOnRank[Rank(rankID)],
*powerDownManagers[Rank(rankID)],
Rank(rankID)));
}
}
else if (config.refreshPolicy == Configuration::RefreshPolicy::PerBank)
@@ -239,8 +250,11 @@ Controller::Controller(const sc_module_name& name, const Configuration& config,
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
{
// TODO: remove bankMachines in constructor
refreshManagers.push_back(std::make_unique<RefreshManagerPerBank>
(config, bankMachinesOnRank[Rank(rankID)], *powerDownManagers[Rank(rankID)], Rank(rankID)));
refreshManagers.push_back(
std::make_unique<RefreshManagerPerBank>(config,
bankMachinesOnRank[Rank(rankID)],
*powerDownManagers[Rank(rankID)],
Rank(rankID)));
}
}
else if (config.refreshPolicy == Configuration::RefreshPolicy::Per2Bank)
@@ -248,8 +262,11 @@ Controller::Controller(const sc_module_name& name, const Configuration& config,
for (unsigned rankID = 0; rankID < memSpec.ranksPerChannel; rankID++)
{
// TODO: remove bankMachines in constructor
refreshManagers.push_back(std::make_unique<RefreshManagerPer2Bank>
(config, bankMachinesOnRank[Rank(rankID)], *powerDownManagers[Rank(rankID)], Rank(rankID)));
refreshManagers.push_back(
std::make_unique<RefreshManagerPer2Bank>(config,
bankMachinesOnRank[Rank(rankID)],
*powerDownManagers[Rank(rankID)],
Rank(rankID)));
}
}
else
@@ -310,7 +327,8 @@ void Controller::controllerMethod()
{
Command command = std::get<CommandTuple::Command>(it);
tlm_generic_payload* trans = std::get<CommandTuple::Payload>(it);
std::get<CommandTuple::Timestamp>(it) = checker->timeToSatisfyConstraints(command, *trans);
std::get<CommandTuple::Timestamp>(it) =
checker->timeToSatisfyConstraints(command, *trans);
}
commandTuple = cmdMux->selectCommand(readyCommands);
Command command = std::get<CommandTuple::Command>(commandTuple);
@@ -328,13 +346,15 @@ void Controller::controllerMethod()
else if (command.isGroupCommand())
{
for (std::size_t bankID = (static_cast<std::size_t>(bank) % memSpec.banksPerGroup);
bankID < memSpec.banksPerRank; bankID += memSpec.banksPerGroup)
bankID < memSpec.banksPerRank;
bankID += memSpec.banksPerGroup)
bankMachinesOnRank[rank][Bank(bankID)]->update(command);
}
else if (command.is2BankCommand())
{
bankMachines[bank]->update(command);
bankMachines[Bank(static_cast<std::size_t>(bank) + memSpec.getPer2BankOffset())]->update(command);
bankMachines[Bank(static_cast<std::size_t>(bank) + memSpec.getPer2BankOffset())]
->update(command);
}
else // if (isBankCommand(command))
bankMachines[bank]->update(command);
@@ -347,10 +367,10 @@ void Controller::controllerMethod()
{
scheduler->removeRequest(*trans);
manageRequests(thinkDelayFw);
respQueue->insertPayload(trans, sc_time_stamp()
+ thinkDelayFw + phyDelayFw
+ memSpec.getIntervalOnDataStrobe(command, *trans).end
+ phyDelayBw + thinkDelayBw);
respQueue->insertPayload(trans,
sc_time_stamp() + thinkDelayFw + phyDelayFw +
memSpec.getIntervalOnDataStrobe(command, *trans).end +
phyDelayBw + thinkDelayBw);
sc_time triggerTime = respQueue->getTriggerTime();
if (triggerTime != scMaxTime)
@@ -369,7 +389,8 @@ void Controller::controllerMethod()
readyCmdBlocked = true;
}
// (6) Restart bank machines, refresh managers and power-down managers to issue new requests for the future
// (6) Restart bank machines, refresh managers and power-down managers to issue new requests for
// the future
sc_time timeForNextTrigger = scMaxTime;
sc_time localTime;
for (auto& it : bankMachines)
@@ -420,7 +441,8 @@ void Controller::controllerMethod()
controllerEvent.notify(timeForNextTrigger - sc_time_stamp());
}
tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload& trans, tlm_phase& phase, sc_time& delay)
tlm_sync_enum
Controller::nb_transport_fw(tlm_generic_payload& trans, tlm_phase& phase, sc_time& delay)
{
if (phase == BEGIN_REQ)
{
@@ -434,17 +456,18 @@ tlm_sync_enum Controller::nb_transport_fw(tlm_generic_payload& trans, tlm_phase&
endRespEvent.notify(delay);
}
else
SC_REPORT_FATAL("Controller", "nb_transport_fw in controller was triggered with unknown phase");
SC_REPORT_FATAL("Controller",
"nb_transport_fw in controller was triggered with unknown phase");
PRINTDEBUGMESSAGE(name(), "[fw] " + getPhaseName(phase) + " notification in " +
delay.to_string());
PRINTDEBUGMESSAGE(name(),
"[fw] " + getPhaseName(phase) + " notification in " + delay.to_string());
return TLM_ACCEPTED;
}
tlm_sync_enum Controller::nb_transport_bw([[maybe_unused]] tlm_generic_payload &trans,
[[maybe_unused]] tlm_phase &phase,
[[maybe_unused]] sc_time &delay)
tlm_sync_enum Controller::nb_transport_bw([[maybe_unused]] tlm_generic_payload& trans,
[[maybe_unused]] tlm_phase& phase,
[[maybe_unused]] sc_time& delay)
{
SC_REPORT_FATAL("Controller", "nb_transport_bw of controller must not be called!");
return TLM_ACCEPTED;
@@ -465,30 +488,38 @@ void Controller::manageRequests(const sc_time& delay)
{
if (transToAcquire.payload != nullptr && transToAcquire.arrival <= sc_time_stamp())
{
// TODO: here we assume that the scheduler always has space not only for a single burst transaction
// TODO: here we assume that the scheduler always has space not only for a single burst
// transaction
// but for a maximum size transaction
if (scheduler->hasBufferSpace())
{
if (totalNumberOfPayloads == 0)
idleTimeCollector.end();
totalNumberOfPayloads++; // seems to be ok
totalNumberOfPayloads++; // seems to be ok
transToAcquire.payload->acquire();
// Align address to minimum burst length
uint64_t alignedAddress = transToAcquire.payload->get_address() & ~(minBytesPerBurst - UINT64_C(1));
uint64_t alignedAddress =
transToAcquire.payload->get_address() & ~(minBytesPerBurst - UINT64_C(1));
transToAcquire.payload->set_address(alignedAddress);
// continuous block of data that can be fetched with a single burst
if ((alignedAddress / maxBytesPerBurst)
== ((alignedAddress + transToAcquire.payload->get_data_length() - 1) / maxBytesPerBurst))
if ((alignedAddress / maxBytesPerBurst) ==
((alignedAddress + transToAcquire.payload->get_data_length() - 1) /
maxBytesPerBurst))
{
DecodedAddress decodedAddress = addressDecoder.decodeAddress(transToAcquire.payload->get_address());
ControllerExtension::setAutoExtension(*transToAcquire.payload, nextChannelPayloadIDToAppend++,
Rank(decodedAddress.rank), BankGroup(decodedAddress.bankgroup),
Bank(decodedAddress.bank), Row(decodedAddress.row),
DecodedAddress decodedAddress =
addressDecoder.decodeAddress(transToAcquire.payload->get_address());
ControllerExtension::setAutoExtension(*transToAcquire.payload,
nextChannelPayloadIDToAppend++,
Rank(decodedAddress.rank),
BankGroup(decodedAddress.bankgroup),
Bank(decodedAddress.bank),
Row(decodedAddress.row),
Column(decodedAddress.column),
transToAcquire.payload->get_data_length() / memSpec.bytesPerBeat);
transToAcquire.payload->get_data_length() /
memSpec.bytesPerBeat);
Rank rank = Rank(decodedAddress.rank);
if (ranksNumberOfPayloads[rank] == 0)
@@ -503,7 +534,7 @@ void Controller::manageRequests(const sc_time& delay)
{
createChildTranses(*transToAcquire.payload);
const std::vector<tlm_generic_payload*>& childTranses =
transToAcquire.payload->get_extension<ParentExtension>()->getChildTranses();
transToAcquire.payload->get_extension<ParentExtension>()->getChildTranses();
for (auto* childTrans : childTranses)
{
Rank rank = ControllerExtension::getRank(*childTrans);
@@ -559,13 +590,15 @@ void Controller::manageResponses()
if (ChildExtension::isChildTrans(*nextTransInRespQueue))
{
tlm_generic_payload& parentTrans = ChildExtension::getParentTrans(*nextTransInRespQueue);
tlm_generic_payload& parentTrans =
ChildExtension::getParentTrans(*nextTransInRespQueue);
if (ParentExtension::notifyChildTransCompletion(parentTrans))
{
transToRelease.payload = &parentTrans;
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay;
if (transToRelease.arrival == sc_time_stamp()) // last payload was released in this cycle
if (transToRelease.arrival ==
sc_time_stamp()) // last payload was released in this cycle
bwDelay = memSpec.tCK;
else
bwDelay = SC_ZERO_TIME;
@@ -585,7 +618,8 @@ void Controller::manageResponses()
transToRelease.payload = nextTransInRespQueue;
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay;
if (transToRelease.arrival == sc_time_stamp()) // last payload was released in this cycle
if (transToRelease.arrival ==
sc_time_stamp()) // last payload was released in this cycle
bwDelay = memSpec.tCK;
else
bwDelay = SC_ZERO_TIME;
@@ -616,7 +650,6 @@ Controller::MemoryManager::~MemoryManager()
trans->reset();
delete trans;
}
}
tlm::tlm_generic_payload& Controller::MemoryManager::allocate()
@@ -626,7 +659,7 @@ tlm::tlm_generic_payload& Controller::MemoryManager::allocate()
return *new tlm_generic_payload(this);
}
tlm_generic_payload *result = freePayloads.top();
tlm_generic_payload* result = freePayloads.top();
freePayloads.pop();
return *result;
}
@@ -675,9 +708,12 @@ void Controller::createChildTranses(tlm::tlm_generic_payload& parentTrans)
for (auto* childTrans : childTranses)
{
DecodedAddress decodedAddress = addressDecoder.decodeAddress(childTrans->get_address());
ControllerExtension::setAutoExtension(*childTrans, nextChannelPayloadIDToAppend,
Rank(decodedAddress.rank), BankGroup(decodedAddress.bankgroup),
Bank(decodedAddress.bank), Row(decodedAddress.row),
ControllerExtension::setAutoExtension(*childTrans,
nextChannelPayloadIDToAppend,
Rank(decodedAddress.rank),
BankGroup(decodedAddress.bankgroup),
Bank(decodedAddress.bank),
Row(decodedAddress.row),
Column(decodedAddress.column),
childTrans->get_data_length() / memSpec.bytesPerBeat);
}

View File

@@ -35,20 +35,20 @@
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include "DRAMSys/controller/ControllerIF.h"
#include "DRAMSys/controller/Command.h"
#include "DRAMSys/controller/BankMachine.h"
#include "DRAMSys/controller/cmdmux/CmdMuxIF.h"
#include "DRAMSys/controller/Command.h"
#include "DRAMSys/controller/ControllerIF.h"
#include "DRAMSys/controller/checker/CheckerIF.h"
#include "DRAMSys/controller/refresh/RefreshManagerIF.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 <vector>
#include <stack>
#include <systemc>
#include <tlm>
#include <vector>
namespace DRAMSys
{
@@ -56,18 +56,23 @@ namespace DRAMSys
class Controller : public ControllerIF
{
public:
Controller(const sc_core::sc_module_name& name, const Configuration& config, const AddressDecoder& addressDecoder);
Controller(const sc_core::sc_module_name& name,
const Configuration& config,
const AddressDecoder& addressDecoder);
SC_HAS_PROCESS(Controller);
protected:
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase,
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase,
sc_core::sc_time& delay) override;
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase,
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase,
sc_core::sc_time& delay) override;
void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) override;
void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) override;
unsigned int transport_dbg(tlm::tlm_generic_payload& trans) override;
virtual void sendToFrontend(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay);
virtual void
sendToFrontend(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay);
virtual void controllerMethod();
@@ -79,7 +84,7 @@ protected:
const sc_core::sc_time phyDelayFw;
const sc_core::sc_time phyDelayBw;
const sc_core::sc_time blockingReadDelay;
const sc_core::sc_time blockingWriteDelay;
const sc_core::sc_time blockingWriteDelay;
private:
unsigned totalNumberOfPayloads = 0;
@@ -117,10 +122,10 @@ private:
{
public:
MemoryManager() = default;
MemoryManager(const MemoryManager &) = delete;
MemoryManager(MemoryManager &&) = delete;
MemoryManager &operator=(const MemoryManager &) = delete;
MemoryManager &operator=(MemoryManager &&) = delete;
MemoryManager(const MemoryManager&) = delete;
MemoryManager(MemoryManager&&) = delete;
MemoryManager& operator=(const MemoryManager&) = delete;
MemoryManager& operator=(MemoryManager&&) = delete;
~MemoryManager() override;
tlm::tlm_generic_payload& allocate();

View File

@@ -37,8 +37,8 @@
#ifndef CONTROLLERIF_H
#define CONTROLLERIF_H
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/common/DebugManager.h"
#include "DRAMSys/configuration/Configuration.h"
#include <iomanip>
#include <systemc>
@@ -55,53 +55,45 @@ class ControllerIF : public sc_core::sc_module
{
public:
// Already create and bind sockets to the virtual functions
tlm_utils::simple_target_socket<ControllerIF> tSocket; // Arbiter side
tlm_utils::simple_target_socket<ControllerIF> tSocket; // Arbiter side
tlm_utils::simple_initiator_socket<ControllerIF> iSocket; // DRAM side
void end_of_simulation() override
{
idleTimeCollector.end();
sc_core::sc_time activeTime = static_cast<double>(numberOfBeatsServed)
/ memSpec.dataRate
* memSpec.tCK
/ memSpec.pseudoChannelsPerChannel;
sc_core::sc_time activeTime = static_cast<double>(numberOfBeatsServed) / memSpec.dataRate *
memSpec.tCK / memSpec.pseudoChannelsPerChannel;
double bandwidth = activeTime / sc_core::sc_time_stamp();
double bandwidthWoIdle = activeTime / (sc_core::sc_time_stamp() - idleTimeCollector.getIdleTime());
double bandwidthWoIdle =
activeTime / (sc_core::sc_time_stamp() - idleTimeCollector.getIdleTime());
double maxBandwidth = (
// fCK in GHz e.g. 1 [GHz] (tCK in ps):
(1000 / memSpec.tCK.to_double())
// DataRate e.g. 2
* memSpec.dataRate
// BusWidth e.g. 8 or 64
* memSpec.bitWidth
// Number of devices that form a rank, e.g., 8 on a DDR3 DIMM
* memSpec.devicesPerRank
// HBM specific, one or two pseudo channels per channel
* memSpec.pseudoChannelsPerChannel);
// fCK in GHz e.g. 1 [GHz] (tCK in ps):
(1000 / memSpec.tCK.to_double())
// DataRate e.g. 2
* memSpec.dataRate
// BusWidth e.g. 8 or 64
* memSpec.bitWidth
// Number of devices that form a rank, e.g., 8 on a DDR3 DIMM
* memSpec.devicesPerRank
// HBM specific, one or two pseudo channels per channel
* memSpec.pseudoChannelsPerChannel);
std::cout << name() << std::string(" Total Time: ")
<< sc_core::sc_time_stamp().to_string()
<< std::endl;
std::cout << name() << std::string(" AVG BW: ")
<< std::fixed << std::setprecision(2)
<< std::setw(6) << (bandwidth * maxBandwidth) << " Gb/s | "
<< std::setw(6) << (bandwidth * maxBandwidth / 8) << " GB/s | "
<< std::setw(6) << (bandwidth * 100) << " %"
<< std::endl;
std::cout << name() << std::string(" AVG BW\\IDLE: ")
<< std::fixed << std::setprecision(2)
<< std::setw(6) << (bandwidthWoIdle * maxBandwidth) << " Gb/s | "
<< std::setw(6) << (bandwidthWoIdle * maxBandwidth / 8) << " GB/s | "
<< std::setw(6) << (bandwidthWoIdle * 100) << " %"
<< std::endl;
std::cout << name() << std::string(" MAX BW: ")
<< std::fixed << std::setprecision(2)
<< std::setw(6) << maxBandwidth << " Gb/s | "
<< std::setw(6) << maxBandwidth / 8 << " GB/s | "
<< std::setw(6) << 100.0 << " %"
<< sc_core::sc_time_stamp().to_string() << std::endl;
std::cout << name() << std::string(" AVG BW: ") << std::fixed
<< std::setprecision(2) << std::setw(6) << (bandwidth * maxBandwidth)
<< " Gb/s | " << std::setw(6) << (bandwidth * maxBandwidth / 8) << " GB/s | "
<< std::setw(6) << (bandwidth * 100) << " %" << std::endl;
std::cout << name() << std::string(" AVG BW\\IDLE: ") << std::fixed
<< std::setprecision(2) << std::setw(6) << (bandwidthWoIdle * maxBandwidth)
<< " Gb/s | " << std::setw(6) << (bandwidthWoIdle * maxBandwidth / 8)
<< " GB/s | " << std::setw(6) << (bandwidthWoIdle * 100) << " %" << std::endl;
std::cout << name() << std::string(" MAX BW: ") << std::fixed
<< std::setprecision(2) << std::setw(6) << maxBandwidth << " Gb/s | "
<< std::setw(6) << maxBandwidth / 8 << " GB/s | " << std::setw(6) << 100.0 << " %"
<< std::endl;
}
@@ -109,8 +101,11 @@ protected:
const MemSpec& memSpec;
// Bind sockets with virtual functions
ControllerIF(const sc_core::sc_module_name& name, const Configuration& config)
: sc_core::sc_module(name), tSocket("tSocket"), iSocket("iSocket"), memSpec(*config.memSpec)
ControllerIF(const sc_core::sc_module_name& name, const Configuration& config) :
sc_core::sc_module(name),
tSocket("tSocket"),
iSocket("iSocket"),
memSpec(*config.memSpec)
{
tSocket.register_nb_transport_fw(this, &ControllerIF::nb_transport_fw);
tSocket.register_transport_dbg(this, &ControllerIF::transport_dbg);
@@ -122,9 +117,11 @@ protected:
SC_HAS_PROCESS(ControllerIF);
// Virtual transport functions
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase,
virtual tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase,
sc_core::sc_time& delay) = 0;
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase,
virtual tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase,
sc_core::sc_time& delay) = 0;
virtual void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) = 0;
virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans) = 0;
@@ -153,10 +150,7 @@ protected:
}
}
sc_core::sc_time getIdleTime()
{
return idleTime;
}
sc_core::sc_time getIdleTime() { return idleTime; }
private:
bool isIdle = false;

View File

@@ -42,10 +42,14 @@ using namespace tlm;
namespace DRAMSys
{
ControllerRecordable::ControllerRecordable(const sc_module_name& name, const Configuration& config,
const AddressDecoder& addressDecoder, TlmRecorder& tlmRecorder)
: Controller(name, config, addressDecoder), tlmRecorder(tlmRecorder),
windowSizeTime(config.windowSize * memSpec.tCK), activeTimeMultiplier(config.memSpec->tCK / config.memSpec->dataRate),
ControllerRecordable::ControllerRecordable(const sc_module_name& name,
const Configuration& config,
const AddressDecoder& addressDecoder,
TlmRecorder& tlmRecorder) :
Controller(name, config, addressDecoder),
tlmRecorder(tlmRecorder),
windowSizeTime(config.windowSize * memSpec.tCK),
activeTimeMultiplier(config.memSpec->tCK / config.memSpec->dataRate),
enableWindowing(config.enableWindowing)
{
if (enableWindowing)
@@ -58,22 +62,24 @@ ControllerRecordable::ControllerRecordable(const sc_module_name& name, const Con
}
}
tlm_sync_enum ControllerRecordable::nb_transport_fw(tlm_generic_payload& trans,
tlm_phase& phase, sc_time& delay)
tlm_sync_enum
ControllerRecordable::nb_transport_fw(tlm_generic_payload& trans, tlm_phase& phase, sc_time& delay)
{
tlmRecorder.recordPhase(trans, phase, delay);
return Controller::nb_transport_fw(trans, phase, delay);
}
tlm_sync_enum ControllerRecordable::nb_transport_bw([[maybe_unused]] tlm_generic_payload &trans,
[[maybe_unused]] tlm_phase &phase,
[[maybe_unused]] sc_time &delay)
tlm_sync_enum ControllerRecordable::nb_transport_bw([[maybe_unused]] tlm_generic_payload& trans,
[[maybe_unused]] tlm_phase& phase,
[[maybe_unused]] sc_time& delay)
{
SC_REPORT_FATAL("Controller", "nb_transport_bw of controller must not be called");
return TLM_ACCEPTED;
}
void ControllerRecordable::sendToFrontend(tlm_generic_payload& payload, tlm_phase& phase, sc_time& delay)
void ControllerRecordable::sendToFrontend(tlm_generic_payload& payload,
tlm_phase& phase,
sc_time& delay)
{
tlmRecorder.recordPhase(payload, phase, delay);
tSocket->nb_transport_bw(payload, phase, delay);
@@ -85,7 +91,7 @@ void ControllerRecordable::controllerMethod()
{
sc_time timeDiff = sc_time_stamp() - lastTimeCalled;
lastTimeCalled = sc_time_stamp();
const std::vector<unsigned> &bufferDepth = scheduler->getBufferDepth();
const std::vector<unsigned>& bufferDepth = scheduler->getBufferDepth();
for (std::size_t index = 0; index < slidingAverageBufferDepth.size(); index++)
slidingAverageBufferDepth[index] += bufferDepth[index] * timeDiff;
@@ -107,7 +113,8 @@ void ControllerRecordable::controllerMethod()
uint64_t windowNumberOfBeatsServed = numberOfBeatsServed - lastNumberOfBeatsServed;
lastNumberOfBeatsServed = numberOfBeatsServed;
sc_time windowActiveTime = activeTimeMultiplier * static_cast<double>(windowNumberOfBeatsServed);
sc_time windowActiveTime =
activeTimeMultiplier * static_cast<double>(windowNumberOfBeatsServed);
double windowAverageBandwidth = windowActiveTime / windowSizeTime;
tlmRecorder.recordBandwidth(sc_time_stamp().to_seconds(), windowAverageBandwidth);
}

View File

@@ -35,8 +35,8 @@
#ifndef CONTROLLERRECORDABLE_H
#define CONTROLLERRECORDABLE_H
#include "DRAMSys/controller/Controller.h"
#include "DRAMSys/common/TlmRecorder.h"
#include "DRAMSys/controller/Controller.h"
#include <systemc>
#include <tlm>
@@ -47,17 +47,22 @@ namespace DRAMSys
class ControllerRecordable final : public Controller
{
public:
ControllerRecordable(const sc_core::sc_module_name& name, const Configuration& config,
const AddressDecoder& addressDecoder, TlmRecorder& tlmRecorder);
ControllerRecordable(const sc_core::sc_module_name& name,
const Configuration& config,
const AddressDecoder& addressDecoder,
TlmRecorder& tlmRecorder);
protected:
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase,
tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase,
sc_core::sc_time& delay) override;
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase,
tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase,
sc_core::sc_time& delay) override;
void sendToFrontend(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase,
sc_core::sc_time &delay) override;
void sendToFrontend(tlm::tlm_generic_payload& payload,
tlm::tlm_phase& phase,
sc_core::sc_time& delay) override;
void controllerMethod() override;

View File

@@ -43,10 +43,10 @@ namespace DRAMSys
class ManagerIF
{
protected:
ManagerIF(const ManagerIF &) = default;
ManagerIF(ManagerIF &&) = default;
ManagerIF &operator=(const ManagerIF &) = default;
ManagerIF &operator=(ManagerIF &&) = default;
ManagerIF(const ManagerIF&) = default;
ManagerIF(ManagerIF&&) = default;
ManagerIF& operator=(const ManagerIF&) = default;
ManagerIF& operator=(ManagerIF&&) = default;
public:
ManagerIF() = default;

View File

@@ -43,16 +43,16 @@ namespace DRAMSys
class CmdMuxIF
{
protected:
CmdMuxIF(const CmdMuxIF &) = default;
CmdMuxIF(CmdMuxIF &&) = default;
CmdMuxIF &operator=(const CmdMuxIF &) = default;
CmdMuxIF &operator=(CmdMuxIF &&) = default;
CmdMuxIF(const CmdMuxIF&) = default;
CmdMuxIF(CmdMuxIF&&) = default;
CmdMuxIF& operator=(const CmdMuxIF&) = default;
CmdMuxIF& operator=(CmdMuxIF&&) = default;
public:
CmdMuxIF() = default;
virtual ~CmdMuxIF() = default;
virtual CommandTuple::Type selectCommand(const ReadyCommands & readyCommands) = 0;
virtual CommandTuple::Type selectCommand(const ReadyCommands& readyCommands) = 0;
};
} // namespace DRAMSys

View File

@@ -41,10 +41,12 @@ using namespace sc_core;
namespace DRAMSys
{
CmdMuxOldest::CmdMuxOldest(const Configuration& config) : memSpec(*config.memSpec) {}
CmdMuxOldest::CmdMuxOldest(const Configuration& config) : memSpec(*config.memSpec)
{
}
CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands &readyCommands)
{
CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands& readyCommands)
{
auto result = readyCommands.cend();
uint64_t lastPayloadID = UINT64_MAX;
uint64_t newPayloadID = 0;
@@ -54,8 +56,9 @@ CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands &readyCommand
for (auto it = readyCommands.cbegin(); it != readyCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID =
ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
@@ -71,12 +74,11 @@ CommandTuple::Type CmdMuxOldest::selectCommand(const ReadyCommands &readyCommand
}
if (result != readyCommands.cend() &&
std::get<CommandTuple::Timestamp>(*result) == sc_time_stamp())
std::get<CommandTuple::Timestamp>(*result) == sc_time_stamp())
return *result;
return {Command::NOP, nullptr, scMaxTime};
}
CmdMuxOldestRasCas::CmdMuxOldestRasCas(const Configuration& config) : memSpec(*config.memSpec)
{
readyRasCommands.reserve(memSpec.banksPerChannel);
@@ -84,7 +86,7 @@ CmdMuxOldestRasCas::CmdMuxOldestRasCas(const Configuration& config) : memSpec(*c
readyRasCasCommands.reserve(2);
}
CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyCommands)
CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands& readyCommands)
{
readyRasCommands.clear();
readyCasCommands.clear();
@@ -109,8 +111,9 @@ CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyC
for (auto it = readyRasCommands.cbegin(); it != readyRasCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID =
ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
@@ -131,8 +134,9 @@ CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyC
for (auto it = readyCasCommands.cbegin(); it != readyCasCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID =
ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
@@ -160,7 +164,8 @@ CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyC
for (auto it = readyRasCasCommands.cbegin(); it != readyRasCasCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it);
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
newPayloadID =
ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
@@ -176,7 +181,7 @@ CommandTuple::Type CmdMuxOldestRasCas::selectCommand(const ReadyCommands &readyC
}
if (result != readyCommands.cend() &&
std::get<CommandTuple::Timestamp>(*result) == sc_time_stamp())
std::get<CommandTuple::Timestamp>(*result) == sc_time_stamp())
return *result;
return {Command::NOP, nullptr, scMaxTime};
}

View File

@@ -35,8 +35,8 @@
#ifndef CMDMUXOLDEST_H
#define CMDMUXOLDEST_H
#include "DRAMSys/controller/cmdmux/CmdMuxIF.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/controller/cmdmux/CmdMuxIF.h"
namespace DRAMSys
{
@@ -45,19 +45,18 @@ class CmdMuxOldest : public CmdMuxIF
{
public:
explicit CmdMuxOldest(const Configuration& config);
CommandTuple::Type selectCommand(const ReadyCommands & readyCommands) override;
CommandTuple::Type selectCommand(const ReadyCommands& readyCommands) override;
private:
const MemSpec& memSpec;
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
};
class CmdMuxOldestRasCas : public CmdMuxIF
{
public:
explicit CmdMuxOldestRasCas(const Configuration& config);
CommandTuple::Type selectCommand(const ReadyCommands & readyCommands) override;
CommandTuple::Type selectCommand(const ReadyCommands& readyCommands) override;
private:
const MemSpec& memSpec;

View File

@@ -41,9 +41,11 @@ using namespace sc_core;
namespace DRAMSys
{
CmdMuxStrict::CmdMuxStrict(const Configuration& config) : memSpec(*config.memSpec) {}
CmdMuxStrict::CmdMuxStrict(const Configuration& config) : memSpec(*config.memSpec)
{
}
CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands &readyCommands)
CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands& readyCommands)
{
auto result = readyCommands.cend();
uint64_t lastPayloadID = UINT64_MAX;
@@ -54,21 +56,24 @@ CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands &readyCommand
for (auto it = readyCommands.cbegin(); it != readyCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID =
ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
if (std::get<CommandTuple::Command>(*it).isRasCommand() || newPayloadID == nextPayloadID)
if (std::get<CommandTuple::Command>(*it).isRasCommand() ||
newPayloadID == nextPayloadID)
{
lastTimestamp = newTimestamp;
lastPayloadID = newPayloadID;
result = it;
}
}
}
else if ((newTimestamp == lastTimestamp) && (newPayloadID < lastPayloadID))
{
if (std::get<CommandTuple::Command>(*it).isRasCommand() || newPayloadID == nextPayloadID)
if (std::get<CommandTuple::Command>(*it).isRasCommand() ||
newPayloadID == nextPayloadID)
{
lastPayloadID = newPayloadID;
result = it;
@@ -77,7 +82,7 @@ CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands &readyCommand
}
if (result != readyCommands.cend() &&
std::get<CommandTuple::Timestamp>(*result) == sc_time_stamp())
std::get<CommandTuple::Timestamp>(*result) == sc_time_stamp())
{
if (std::get<CommandTuple::Command>(*result).isCasCommand())
nextPayloadID++;
@@ -86,7 +91,6 @@ CommandTuple::Type CmdMuxStrict::selectCommand(const ReadyCommands &readyCommand
return {Command::NOP, nullptr, scMaxTime};
}
CmdMuxStrictRasCas::CmdMuxStrictRasCas(const Configuration& config) : memSpec(*config.memSpec)
{
readyRasCommands.reserve(memSpec.banksPerChannel);
@@ -94,7 +98,7 @@ CmdMuxStrictRasCas::CmdMuxStrictRasCas(const Configuration& config) : memSpec(*c
readyRasCasCommands.reserve(2);
}
CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands &readyCommands)
CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands& readyCommands)
{
readyRasCommands.clear();
readyCasCommands.clear();
@@ -119,8 +123,9 @@ CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands &readyC
for (auto it = readyRasCommands.cbegin(); it != readyRasCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it) +
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
memSpec.getCommandLength(std::get<CommandTuple::Command>(*it));
newPayloadID =
ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
@@ -137,7 +142,8 @@ CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands &readyC
for (auto it = readyCasCommands.cbegin(); it != readyCasCommands.cend(); it++)
{
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
newPayloadID =
ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newPayloadID == nextPayloadID)
{
@@ -159,7 +165,8 @@ CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands &readyC
for (auto it = readyRasCasCommands.cbegin(); it != readyRasCasCommands.cend(); it++)
{
newTimestamp = std::get<CommandTuple::Timestamp>(*it);
newPayloadID = ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
newPayloadID =
ControllerExtension::getChannelPayloadID(*std::get<CommandTuple::Payload>(*it));
if (newTimestamp < lastTimestamp)
{
@@ -175,13 +182,13 @@ CommandTuple::Type CmdMuxStrictRasCas::selectCommand(const ReadyCommands &readyC
}
if (result != readyCommands.cend() &&
std::get<CommandTuple::Timestamp>(*result) == sc_time_stamp())
{
if (std::get<CommandTuple::Command>(*result).isCasCommand())
nextPayloadID++;
return *result;
}
return {Command::NOP, nullptr, scMaxTime};
std::get<CommandTuple::Timestamp>(*result) == sc_time_stamp())
{
if (std::get<CommandTuple::Command>(*result).isCasCommand())
nextPayloadID++;
return *result;
}
return {Command::NOP, nullptr, scMaxTime};
}
} // namespace DRAMSys

View File

@@ -35,8 +35,8 @@
#ifndef CMDMUXSTRICT_H
#define CMDMUXSTRICT_H
#include "DRAMSys/controller/cmdmux/CmdMuxIF.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/controller/cmdmux/CmdMuxIF.h"
namespace DRAMSys
{
@@ -45,7 +45,7 @@ class CmdMuxStrict : public CmdMuxIF
{
public:
explicit CmdMuxStrict(const Configuration& config);
CommandTuple::Type selectCommand(const ReadyCommands & readyCommands) override;
CommandTuple::Type selectCommand(const ReadyCommands& readyCommands) override;
private:
uint64_t nextPayloadID = 1;
@@ -57,7 +57,7 @@ class CmdMuxStrictRasCas : public CmdMuxIF
{
public:
explicit CmdMuxStrictRasCas(const Configuration& config);
CommandTuple::Type selectCommand(const ReadyCommands & readyCommands) override;
CommandTuple::Type selectCommand(const ReadyCommands& readyCommands) override;
private:
uint64_t nextPayloadID = 1;

View File

@@ -35,8 +35,8 @@
#ifndef POWERDOWNMANAGERIF_H
#define POWERDOWNMANAGERIF_H
#include "DRAMSys/controller/ManagerIF.h"
#include "DRAMSys/controller/Command.h"
#include "DRAMSys/controller/ManagerIF.h"
#include <systemc>

View File

@@ -98,7 +98,7 @@ void PowerDownManagerStaggered::evaluate()
else if (entryTriggered)
{
nextCommand = Command::PDEP;
for (auto *it : bankMachinesOnRank)
for (auto* it : bankMachinesOnRank)
{
if (it->isActivated())
{
@@ -117,47 +117,49 @@ void PowerDownManagerStaggered::update(Command command)
{
switch (command)
{
case Command::PDEA:
state = State::ActivePdn;
entryTriggered = false;
break;
case Command::PDEP:
state = State::PrechargePdn;
entryTriggered = false;
break;
case Command::SREFEN:
state = State::SelfRefresh;
entryTriggered = false;
enterSelfRefresh = false;
break;
case Command::PDXA:
case Command::PDEA:
state = State::ActivePdn;
entryTriggered = false;
break;
case Command::PDEP:
state = State::PrechargePdn;
entryTriggered = false;
break;
case Command::SREFEN:
state = State::SelfRefresh;
entryTriggered = false;
enterSelfRefresh = false;
break;
case Command::PDXA:
state = State::Idle;
exitTriggered = false;
break;
case Command::PDXP:
state = State::Idle;
exitTriggered = false;
if (controllerIdle)
enterSelfRefresh = true;
break;
case Command::SREFEX:
state = State::ExtraRefresh;
break;
case Command::REFAB:
if (state == State::ExtraRefresh)
{
state = State::Idle;
exitTriggered = false;
break;
case Command::PDXP:
state = State::Idle;
exitTriggered = false;
if (controllerIdle)
enterSelfRefresh = true;
break;
case Command::SREFEX:
state = State::ExtraRefresh;
break;
case Command::REFAB:
if (state == State::ExtraRefresh)
{
state = State::Idle;
exitTriggered = false;
}
else if (controllerIdle)
entryTriggered = true;
break;
case Command::REFPB: case Command::REFP2B: case Command::REFSB:
if (controllerIdle)
entryTriggered = true;
break;
default:
break;
}
else if (controllerIdle)
entryTriggered = true;
break;
case Command::REFPB:
case Command::REFP2B:
case Command::REFSB:
if (controllerIdle)
entryTriggered = true;
break;
default:
break;
}
}

View File

@@ -35,9 +35,9 @@
#ifndef POWERDOWNMANAGERSTAGGERED_H
#define POWERDOWNMANAGERSTAGGERED_H
#include "DRAMSys/controller/powerdown/PowerDownManagerIF.h"
#include "DRAMSys/common/dramExtensions.h"
#include "DRAMSys/controller/checker/CheckerIF.h"
#include "DRAMSys/controller/powerdown/PowerDownManagerIF.h"
#include <systemc>
@@ -60,7 +60,14 @@ public:
void evaluate() override;
private:
enum class State {Idle, ActivePdn, PrechargePdn, SelfRefresh, ExtraRefresh} state = State::Idle;
enum class State
{
Idle,
ActivePdn,
PrechargePdn,
SelfRefresh,
ExtraRefresh
} state = State::Idle;
tlm::tlm_generic_payload powerDownPayload;
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank;
Command nextCommand = Command::NOP;

View File

@@ -44,15 +44,20 @@ using namespace tlm;
namespace DRAMSys
{
RefreshManagerAllBank::RefreshManagerAllBank(const Configuration& config,
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager, Rank rank)
: memSpec(*config.memSpec), bankMachinesOnRank(bankMachinesOnRank),
powerDownManager(powerDownManager), maxPostponed(static_cast<int>(config.refreshMaxPostponed)),
maxPulledin(-static_cast<int>(config.refreshMaxPulledin)), refreshManagement(config.refreshManagement)
RefreshManagerAllBank::RefreshManagerAllBank(
const Configuration& config,
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager,
Rank rank) :
memSpec(*config.memSpec),
bankMachinesOnRank(bankMachinesOnRank),
powerDownManager(powerDownManager),
maxPostponed(static_cast<int>(config.refreshMaxPostponed)),
maxPulledin(-static_cast<int>(config.refreshMaxPulledin)),
refreshManagement(config.refreshManagement)
{
timeForNextTrigger = getTimeForFirstTrigger(memSpec.tCK, memSpec.getRefreshIntervalAB(),
rank, memSpec.ranksPerChannel);
timeForNextTrigger = getTimeForFirstTrigger(
memSpec.tCK, memSpec.getRefreshIntervalAB(), rank, memSpec.ranksPerChannel);
setUpDummy(refreshPayload, 0, rank);
}
@@ -178,49 +183,54 @@ void RefreshManagerAllBank::update(Command command)
{
switch (command)
{
case Command::ACT:
activatedBanks++;
break;
case Command::PREPB: case Command::RDA: case Command::WRA: case Command::MWRA:
activatedBanks--;
break;
case Command::PREAB:
activatedBanks = 0;
break;
case Command::REFAB:
if (sleeping)
{
// Refresh command after SREFEX
state = State::Regular; // TODO: check if this assignment is necessary
timeForNextTrigger = sc_time_stamp() + memSpec.getRefreshIntervalAB();
sleeping = false;
}
else
{
if (state == State::Pulledin)
flexibilityCounter--;
else
state = State::Pulledin;
if (flexibilityCounter == maxPulledin)
{
state = State::Regular;
timeForNextTrigger += memSpec.getRefreshIntervalAB();
}
}
break;
case Command::PDEA: case Command::PDEP:
sleeping = true;
break;
case Command::SREFEN:
sleeping = true;
timeForNextTrigger = scMaxTime;
break;
case Command::PDXA: case Command::PDXP:
case Command::ACT:
activatedBanks++;
break;
case Command::PREPB:
case Command::RDA:
case Command::WRA:
case Command::MWRA:
activatedBanks--;
break;
case Command::PREAB:
activatedBanks = 0;
break;
case Command::REFAB:
if (sleeping)
{
// Refresh command after SREFEX
state = State::Regular; // TODO: check if this assignment is necessary
timeForNextTrigger = sc_time_stamp() + memSpec.getRefreshIntervalAB();
sleeping = false;
break;
default:
break;
}
else
{
if (state == State::Pulledin)
flexibilityCounter--;
else
state = State::Pulledin;
if (flexibilityCounter == maxPulledin)
{
state = State::Regular;
timeForNextTrigger += memSpec.getRefreshIntervalAB();
}
}
break;
case Command::PDEA:
case Command::PDEP:
sleeping = true;
break;
case Command::SREFEN:
sleeping = true;
timeForNextTrigger = scMaxTime;
break;
case Command::PDXA:
case Command::PDXP:
sleeping = false;
break;
default:
break;
}
}

View File

@@ -35,14 +35,14 @@
#ifndef REFRESHMANAGERALLBANK_H
#define REFRESHMANAGERALLBANK_H
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
#include "DRAMSys/controller/checker/CheckerIF.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/configuration/memspec/MemSpec.h"
#include "DRAMSys/controller/checker/CheckerIF.h"
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
#include <vector>
#include <systemc>
#include <tlm>
#include <vector>
namespace DRAMSys
{
@@ -53,8 +53,10 @@ class PowerDownManagerIF;
class RefreshManagerAllBank final : public RefreshManagerIF
{
public:
RefreshManagerAllBank(const Configuration& config, ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager, Rank rank);
RefreshManagerAllBank(const Configuration& config,
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager,
Rank rank);
CommandTuple::Type getNextCommand() override;
void evaluate() override;
@@ -62,7 +64,11 @@ public:
sc_core::sc_time getTimeForNextTrigger() override;
private:
enum class State {Regular, Pulledin} state = State::Regular;
enum class State
{
Regular,
Pulledin
} state = State::Regular;
const MemSpec& memSpec;
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank;
PowerDownManagerIF& powerDownManager;

View File

@@ -49,6 +49,7 @@ public:
void evaluate() override {}
void update([[maybe_unused]] Command command) override {}
sc_core::sc_time getTimeForNextTrigger() override;
private:
const sc_core::sc_time scMaxTime = sc_core::sc_max_time();
};

View File

@@ -35,9 +35,9 @@
#ifndef REFRESHMANAGERIF_H
#define REFRESHMANAGERIF_H
#include "DRAMSys/controller/ManagerIF.h"
#include "DRAMSys/controller/Command.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/controller/Command.h"
#include "DRAMSys/controller/ManagerIF.h"
#include <cmath>
#include <systemc>
@@ -51,8 +51,10 @@ public:
virtual sc_core::sc_time getTimeForNextTrigger() = 0;
protected:
static sc_core::sc_time getTimeForFirstTrigger(const sc_core::sc_time& tCK, const sc_core::sc_time &refreshInterval,
Rank rank, unsigned numberOfRanks)
static sc_core::sc_time getTimeForFirstTrigger(const sc_core::sc_time& tCK,
const sc_core::sc_time& refreshInterval,
Rank rank,
unsigned numberOfRanks)
{
// Calculate bit-reversal rank ID
auto rankID = static_cast<unsigned>(rank);
@@ -73,7 +75,8 @@ protected:
}
// Use bit-reversal order for refreshes on ranks
sc_core::sc_time timeForFirstTrigger = refreshInterval - reverseRankID * (refreshInterval / numberOfRanks);
sc_core::sc_time timeForFirstTrigger =
refreshInterval - reverseRankID * (refreshInterval / numberOfRanks);
timeForFirstTrigger = std::ceil(timeForFirstTrigger / tCK) * tCK;
return timeForFirstTrigger;

View File

@@ -43,28 +43,39 @@ using namespace tlm;
namespace DRAMSys
{
RefreshManagerPer2Bank::RefreshManagerPer2Bank(const Configuration& config,
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager, Rank rank)
: memSpec(*config.memSpec), powerDownManager(powerDownManager),
RefreshManagerPer2Bank::RefreshManagerPer2Bank(
const Configuration& config,
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager,
Rank rank) :
memSpec(*config.memSpec),
powerDownManager(powerDownManager),
maxPostponed(static_cast<int>(config.refreshMaxPostponed * memSpec.banksPerRank / 2)),
maxPulledin(-static_cast<int>(config.refreshMaxPulledin * memSpec.banksPerRank / 2))
{
timeForNextTrigger = getTimeForFirstTrigger(memSpec.tCK, memSpec.getRefreshIntervalP2B(), rank,
memSpec.ranksPerChannel);
timeForNextTrigger = getTimeForFirstTrigger(
memSpec.tCK, memSpec.getRefreshIntervalP2B(), rank, memSpec.ranksPerChannel);
// each bank pair has one payload (e.g. 0-8, 1-9, 2-10, 3-11, ...)
for (unsigned outerID = 0; outerID < memSpec.banksPerRank; outerID += (memSpec.getPer2BankOffset() * 2))
for (unsigned outerID = 0; outerID < memSpec.banksPerRank;
outerID += (memSpec.getPer2BankOffset() * 2))
{
for (unsigned bankID = outerID; bankID < (outerID + memSpec.getPer2BankOffset()); bankID++)
{
Bank firstBank = Bank(bankID);
Bank secondBank = Bank(bankID + memSpec.getPer2BankOffset());
setUpDummy(refreshPayloads[bankMachinesOnRank[firstBank]], 0, rank,
bankMachinesOnRank[firstBank]->getBankGroup(), bankMachinesOnRank[firstBank]->getBank());
setUpDummy(refreshPayloads[bankMachinesOnRank[secondBank]], 0, rank,
bankMachinesOnRank[secondBank]->getBankGroup(), bankMachinesOnRank[secondBank]->getBank());
allBankMachines.push_back({bankMachinesOnRank[firstBank], bankMachinesOnRank[secondBank]});
setUpDummy(refreshPayloads[bankMachinesOnRank[firstBank]],
0,
rank,
bankMachinesOnRank[firstBank]->getBankGroup(),
bankMachinesOnRank[firstBank]->getBank());
setUpDummy(refreshPayloads[bankMachinesOnRank[secondBank]],
0,
rank,
bankMachinesOnRank[secondBank]->getBankGroup(),
bankMachinesOnRank[secondBank]->getBank());
allBankMachines.push_back(
{bankMachinesOnRank[firstBank], bankMachinesOnRank[secondBank]});
}
}
@@ -102,7 +113,9 @@ void RefreshManagerPer2Bank::evaluate()
if (!skipSelection)
{
currentIterator = remainingBankMachines.begin();
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
for (auto bankIt = remainingBankMachines.begin();
bankIt != remainingBankMachines.end();
bankIt++)
{
bool pairIsBusy = false;
for (const auto* pairIt : *bankIt)
@@ -131,7 +144,7 @@ void RefreshManagerPer2Bank::evaluate()
nextCommand = Command::REFP2B;
currentRefreshPayload = &refreshPayloads.at(currentIterator->front());
for (auto *it : *currentIterator)
for (auto* it : *currentIterator)
{
if (it->isActivated())
{
@@ -139,18 +152,18 @@ void RefreshManagerPer2Bank::evaluate()
currentRefreshPayload = &refreshPayloads.at(it);
break;
}
}
}
// TODO: banks should already be blocked for precharge and selection should be skipped
if (nextCommand == Command::REFP2B && forcedRefresh)
{
for (auto* it : *currentIterator)
it->block();
skipSelection = true;
}
return;
// TODO: banks should already be blocked for precharge and selection should be skipped
if (nextCommand == Command::REFP2B && forcedRefresh)
{
for (auto* it : *currentIterator)
it->block();
skipSelection = true;
}
return;
}
// if (state == RmState::Pulledin)
bool allBankPairsBusy = true;
@@ -159,7 +172,7 @@ void RefreshManagerPer2Bank::evaluate()
bankIt++)
{
bool pairIsBusy = false;
for (const auto *pairIt : *bankIt)
for (const auto* pairIt : *bankIt)
{
if (!pairIt->isIdle())
{
@@ -184,7 +197,7 @@ void RefreshManagerPer2Bank::evaluate()
nextCommand = Command::REFP2B;
currentRefreshPayload = &refreshPayloads.at(currentIterator->front());
for (auto *it : *currentIterator)
for (auto* it : *currentIterator)
{
if (it->isActivated())
{
@@ -201,45 +214,47 @@ void RefreshManagerPer2Bank::update(Command command)
{
switch (command)
{
case Command::REFP2B:
skipSelection = false;
remainingBankMachines.erase(currentIterator);
if (remainingBankMachines.empty())
remainingBankMachines = allBankMachines;
currentIterator = remainingBankMachines.begin();
if (state == State::Pulledin)
flexibilityCounter--;
else
state = State::Pulledin;
if (flexibilityCounter == maxPulledin)
{
state = State::Regular;
timeForNextTrigger += memSpec.getRefreshIntervalP2B();
}
break;
case Command::REFAB:
// Refresh command after SREFEX
state = State::Regular; // TODO: check if this assignment is necessary
timeForNextTrigger = sc_time_stamp() + memSpec.getRefreshIntervalP2B();
sleeping = false;
case Command::REFP2B:
skipSelection = false;
remainingBankMachines.erase(currentIterator);
if (remainingBankMachines.empty())
remainingBankMachines = allBankMachines;
currentIterator = remainingBankMachines.begin();
skipSelection = false;
break;
case Command::PDEA: case Command::PDEP:
sleeping = true;
break;
case Command::SREFEN:
sleeping = true;
timeForNextTrigger = scMaxTime;
break;
case Command::PDXA: case Command::PDXP:
sleeping = false;
break;
default:
break;
currentIterator = remainingBankMachines.begin();
if (state == State::Pulledin)
flexibilityCounter--;
else
state = State::Pulledin;
if (flexibilityCounter == maxPulledin)
{
state = State::Regular;
timeForNextTrigger += memSpec.getRefreshIntervalP2B();
}
break;
case Command::REFAB:
// Refresh command after SREFEX
state = State::Regular; // TODO: check if this assignment is necessary
timeForNextTrigger = sc_time_stamp() + memSpec.getRefreshIntervalP2B();
sleeping = false;
remainingBankMachines = allBankMachines;
currentIterator = remainingBankMachines.begin();
skipSelection = false;
break;
case Command::PDEA:
case Command::PDEP:
sleeping = true;
break;
case Command::SREFEN:
sleeping = true;
timeForNextTrigger = scMaxTime;
break;
case Command::PDXA:
case Command::PDXP:
sleeping = false;
break;
default:
break;
}
}

View File

@@ -35,16 +35,16 @@
#ifndef REFRESHMANAGERPER2BANK_H
#define REFRESHMANAGERPER2BANK_H
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
#include "DRAMSys/controller/checker/CheckerIF.h"
#include "DRAMSys/configuration/memspec/MemSpec.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/configuration/memspec/MemSpec.h"
#include "DRAMSys/controller/checker/CheckerIF.h"
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
#include <vector>
#include <list>
#include <unordered_map>
#include <systemc>
#include <tlm>
#include <unordered_map>
#include <vector>
namespace DRAMSys
{
@@ -55,8 +55,10 @@ class PowerDownManagerIF;
class RefreshManagerPer2Bank final : public RefreshManagerIF
{
public:
RefreshManagerPer2Bank(const Configuration& config, ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager, Rank rank);
RefreshManagerPer2Bank(const Configuration& config,
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager,
Rank rank);
CommandTuple::Type getNextCommand() override;
void evaluate() override;
@@ -64,7 +66,11 @@ public:
sc_core::sc_time getTimeForNextTrigger() override;
private:
enum class State {Regular, Pulledin} state = State::Regular;
enum class State
{
Regular,
Pulledin
} state = State::Regular;
const MemSpec& memSpec;
PowerDownManagerIF& powerDownManager;
std::unordered_map<BankMachine*, tlm::tlm_generic_payload> refreshPayloads;

View File

@@ -43,15 +43,18 @@ using namespace tlm;
namespace DRAMSys
{
RefreshManagerPerBank::RefreshManagerPerBank(const Configuration& config,
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager, Rank rank)
: memSpec(*config.memSpec), powerDownManager(powerDownManager),
RefreshManagerPerBank::RefreshManagerPerBank(
const Configuration& config,
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager,
Rank rank) :
memSpec(*config.memSpec),
powerDownManager(powerDownManager),
maxPostponed(static_cast<int>(config.refreshMaxPostponed * memSpec.banksPerRank)),
maxPulledin(-static_cast<int>(config.refreshMaxPulledin * memSpec.banksPerRank))
{
timeForNextTrigger = getTimeForFirstTrigger(memSpec.tCK, memSpec.getRefreshIntervalPB(), rank,
memSpec.ranksPerChannel);
timeForNextTrigger = getTimeForFirstTrigger(
memSpec.tCK, memSpec.getRefreshIntervalPB(), rank, memSpec.ranksPerChannel);
for (auto* it : bankMachinesOnRank)
{
setUpDummy(refreshPayloads[it], 0, rank, it->getBankGroup(), it->getBank());
@@ -92,7 +95,8 @@ void RefreshManagerPerBank::evaluate()
{
currentIterator = remainingBankMachines.begin();
for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end(); it++)
for (auto it = remainingBankMachines.begin(); it != remainingBankMachines.end();
it++)
{
if ((*it)->isIdle())
{
@@ -125,7 +129,7 @@ void RefreshManagerPerBank::evaluate()
}
return;
}
// if (state == RmState::Pulledin)
bool allBanksBusy = true;
@@ -159,45 +163,47 @@ void RefreshManagerPerBank::update(Command command)
{
switch (command)
{
case Command::REFPB:
skipSelection = false;
remainingBankMachines.erase(currentIterator);
if (remainingBankMachines.empty())
remainingBankMachines = allBankMachines;
currentIterator = remainingBankMachines.begin();
if (state == State::Pulledin)
flexibilityCounter--;
else
state = State::Pulledin;
if (flexibilityCounter == maxPulledin)
{
state = State::Regular;
timeForNextTrigger += memSpec.getRefreshIntervalPB();
}
break;
case Command::REFAB:
// Refresh command after SREFEX
state = State::Regular; // TODO: check if this assignment is necessary
timeForNextTrigger = sc_time_stamp() + memSpec.getRefreshIntervalPB();
sleeping = false;
case Command::REFPB:
skipSelection = false;
remainingBankMachines.erase(currentIterator);
if (remainingBankMachines.empty())
remainingBankMachines = allBankMachines;
currentIterator = remainingBankMachines.begin();
skipSelection = false;
break;
case Command::PDEA: case Command::PDEP:
sleeping = true;
break;
case Command::SREFEN:
sleeping = true;
timeForNextTrigger = scMaxTime;
break;
case Command::PDXA: case Command::PDXP:
sleeping = false;
break;
default:
break;
currentIterator = remainingBankMachines.begin();
if (state == State::Pulledin)
flexibilityCounter--;
else
state = State::Pulledin;
if (flexibilityCounter == maxPulledin)
{
state = State::Regular;
timeForNextTrigger += memSpec.getRefreshIntervalPB();
}
break;
case Command::REFAB:
// Refresh command after SREFEX
state = State::Regular; // TODO: check if this assignment is necessary
timeForNextTrigger = sc_time_stamp() + memSpec.getRefreshIntervalPB();
sleeping = false;
remainingBankMachines = allBankMachines;
currentIterator = remainingBankMachines.begin();
skipSelection = false;
break;
case Command::PDEA:
case Command::PDEP:
sleeping = true;
break;
case Command::SREFEN:
sleeping = true;
timeForNextTrigger = scMaxTime;
break;
case Command::PDXA:
case Command::PDXP:
sleeping = false;
break;
default:
break;
}
}

View File

@@ -35,16 +35,16 @@
#ifndef REFRESHMANAGERPERBANK_H
#define REFRESHMANAGERPERBANK_H
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
#include "DRAMSys/controller/checker/CheckerIF.h"
#include "DRAMSys/configuration/memspec/MemSpec.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/configuration/memspec/MemSpec.h"
#include "DRAMSys/controller/checker/CheckerIF.h"
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
#include <vector>
#include <list>
#include <unordered_map>
#include <systemc>
#include <tlm>
#include <unordered_map>
#include <vector>
namespace DRAMSys
{
@@ -55,8 +55,10 @@ class PowerDownManagerIF;
class RefreshManagerPerBank final : public RefreshManagerIF
{
public:
RefreshManagerPerBank(const Configuration& config, ControllerVector<Bank, BankMachine *>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager, Rank rank);
RefreshManagerPerBank(const Configuration& config,
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager,
Rank rank);
CommandTuple::Type getNextCommand() override;
void evaluate() override;
@@ -64,7 +66,11 @@ public:
sc_core::sc_time getTimeForNextTrigger() override;
private:
enum class State {Regular, Pulledin} state = State::Regular;
enum class State
{
Regular,
Pulledin
} state = State::Regular;
const MemSpec& memSpec;
PowerDownManagerIF& powerDownManager;
std::unordered_map<BankMachine*, tlm::tlm_generic_payload> refreshPayloads;

View File

@@ -43,25 +43,31 @@ using namespace tlm;
namespace DRAMSys
{
RefreshManagerSameBank::RefreshManagerSameBank(const Configuration& config,
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager, Rank rank)
: memSpec(*config.memSpec), powerDownManager(powerDownManager),
RefreshManagerSameBank::RefreshManagerSameBank(
const Configuration& config,
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager,
Rank rank) :
memSpec(*config.memSpec),
powerDownManager(powerDownManager),
maxPostponed(static_cast<int>(config.refreshMaxPostponed * memSpec.banksPerGroup)),
maxPulledin(-static_cast<int>(config.refreshMaxPulledin * memSpec.banksPerGroup)),
refreshManagement(config.refreshManagement)
{
timeForNextTrigger = getTimeForFirstTrigger(memSpec.tCK, memSpec.getRefreshIntervalSB(), rank,
memSpec.ranksPerChannel);
timeForNextTrigger = getTimeForFirstTrigger(
memSpec.tCK, memSpec.getRefreshIntervalSB(), rank, memSpec.ranksPerChannel);
// each same-bank group has one payload (e.g. 0-4-8-12-16-20-24-28)
refreshPayloads = std::vector<tlm_generic_payload>(memSpec.banksPerGroup);
for (unsigned bankID = 0; bankID < memSpec.banksPerGroup; bankID++)
{
// rank 0: bank group 0, bank 0 - 3; rank 1: bank group 8, bank 32 - 35
setUpDummy(refreshPayloads[bankID], 0, rank, bankMachinesOnRank[Bank(bankID)]->getBankGroup(),
setUpDummy(refreshPayloads[bankID],
0,
rank,
bankMachinesOnRank[Bank(bankID)]->getBankGroup(),
bankMachinesOnRank[Bank(bankID)]->getBank());
allBankMachines.emplace_back(std::vector<BankMachine *>(memSpec.groupsPerRank));
allBankMachines.emplace_back(std::vector<BankMachine*>(memSpec.groupsPerRank));
}
// allBankMachines: ((0-4-8-12-16-20-24-28), (1-5-9-13-17-21-25-29), ...)
@@ -80,7 +86,8 @@ RefreshManagerSameBank::RefreshManagerSameBank(const Configuration& config,
CommandTuple::Type RefreshManagerSameBank::getNextCommand()
{
return {nextCommand,
&refreshPayloads[static_cast<std::size_t>(currentIterator->front()->getBank()) % memSpec.banksPerGroup],
&refreshPayloads[static_cast<std::size_t>(currentIterator->front()->getBank()) %
memSpec.banksPerGroup],
SC_ZERO_TIME};
}
@@ -108,7 +115,9 @@ void RefreshManagerSameBank::evaluate()
if (!skipSelection)
{
currentIterator = remainingBankMachines.begin();
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
for (auto bankIt = remainingBankMachines.begin();
bankIt != remainingBankMachines.end();
bankIt++)
{
bool groupIsBusy = false;
for (const auto* groupIt : *bankIt)
@@ -134,7 +143,7 @@ void RefreshManagerSameBank::evaluate()
timeForNextTrigger += memSpec.getRefreshIntervalSB();
}
else
{
{
nextCommand = Command::REFSB;
for (const auto* it : *currentIterator)
{
@@ -145,8 +154,8 @@ void RefreshManagerSameBank::evaluate()
}
}
// TODO: banks should already be blocked for precharge and selection should be skipped
// only check for forced refresh, also block for PRESB
// TODO: banks should already be blocked for precharge and selection should be
// skipped only check for forced refresh, also block for PRESB
if (nextCommand == Command::REFSB && forcedRefresh)
{
for (auto* it : *currentIterator)
@@ -161,7 +170,8 @@ void RefreshManagerSameBank::evaluate()
bool allGroupsBusy = true;
currentIterator = remainingBankMachines.begin();
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end(); bankIt++)
for (auto bankIt = remainingBankMachines.begin(); bankIt != remainingBankMachines.end();
bankIt++)
{
bool groupIsBusy = false;
for (const auto* groupIt : *bankIt)
@@ -277,45 +287,47 @@ void RefreshManagerSameBank::update(Command command)
{
switch (command)
{
case Command::REFSB:
skipSelection = false;
remainingBankMachines.erase(currentIterator);
if (remainingBankMachines.empty())
remainingBankMachines = allBankMachines;
currentIterator = remainingBankMachines.begin();
if (state == State::Pulledin)
flexibilityCounter--;
else
state = State::Pulledin;
if (flexibilityCounter == maxPulledin)
{
state = State::Regular;
timeForNextTrigger += memSpec.getRefreshIntervalSB();
}
break;
case Command::REFAB:
// Refresh command after SREFEX
state = State::Regular; // TODO: check if this assignment is necessary
timeForNextTrigger = sc_time_stamp() + memSpec.getRefreshIntervalSB();
sleeping = false;
case Command::REFSB:
skipSelection = false;
remainingBankMachines.erase(currentIterator);
if (remainingBankMachines.empty())
remainingBankMachines = allBankMachines;
currentIterator = remainingBankMachines.begin();
skipSelection = false;
break;
case Command::PDEA: case Command::PDEP:
sleeping = true;
break;
case Command::SREFEN:
sleeping = true;
timeForNextTrigger = scMaxTime;
break;
case Command::PDXA: case Command::PDXP:
sleeping = false;
break;
default:
break;
currentIterator = remainingBankMachines.begin();
if (state == State::Pulledin)
flexibilityCounter--;
else
state = State::Pulledin;
if (flexibilityCounter == maxPulledin)
{
state = State::Regular;
timeForNextTrigger += memSpec.getRefreshIntervalSB();
}
break;
case Command::REFAB:
// Refresh command after SREFEX
state = State::Regular; // TODO: check if this assignment is necessary
timeForNextTrigger = sc_time_stamp() + memSpec.getRefreshIntervalSB();
sleeping = false;
remainingBankMachines = allBankMachines;
currentIterator = remainingBankMachines.begin();
skipSelection = false;
break;
case Command::PDEA:
case Command::PDEP:
sleeping = true;
break;
case Command::SREFEN:
sleeping = true;
timeForNextTrigger = scMaxTime;
break;
case Command::PDXA:
case Command::PDXP:
sleeping = false;
break;
default:
break;
}
}

View File

@@ -35,15 +35,15 @@
#ifndef REFRESHMANAGERSAMEBANK_H
#define REFRESHMANAGERSAMEBANK_H
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
#include "DRAMSys/controller/checker/CheckerIF.h"
#include "DRAMSys/configuration/memspec/MemSpec.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/configuration/memspec/MemSpec.h"
#include "DRAMSys/controller/checker/CheckerIF.h"
#include "DRAMSys/controller/refresh/RefreshManagerIF.h"
#include <vector>
#include <list>
#include <systemc>
#include <tlm>
#include <vector>
namespace DRAMSys
{
@@ -54,8 +54,10 @@ class PowerDownManagerIF;
class RefreshManagerSameBank final : public RefreshManagerIF
{
public:
RefreshManagerSameBank(const Configuration& config, ControllerVector<Bank, BankMachine *>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager, Rank rank);
RefreshManagerSameBank(const Configuration& config,
ControllerVector<Bank, BankMachine*>& bankMachinesOnRank,
PowerDownManagerIF& powerDownManager,
Rank rank);
CommandTuple::Type getNextCommand() override;
void evaluate() override;
@@ -63,16 +65,20 @@ public:
sc_core::sc_time getTimeForNextTrigger() override;
private:
enum class State {Regular, Pulledin} state = State::Regular;
enum class State
{
Regular,
Pulledin
} state = State::Regular;
const MemSpec& memSpec;
PowerDownManagerIF& powerDownManager;
std::vector<tlm::tlm_generic_payload> refreshPayloads;
sc_core::sc_time timeForNextTrigger = sc_core::sc_max_time();
Command nextCommand = Command::NOP;
std::list<std::vector<BankMachine *>> remainingBankMachines;
std::list<std::vector<BankMachine *>> allBankMachines;
std::list<std::vector<BankMachine *>>::iterator currentIterator;
std::list<std::vector<BankMachine*>> remainingBankMachines;
std::list<std::vector<BankMachine*>> allBankMachines;
std::list<std::vector<BankMachine*>>::iterator currentIterator;
int flexibilityCounter = 0;
const int maxPostponed;

View File

@@ -37,10 +37,10 @@
#include "DRAMSys/controller/respqueue/RespQueueIF.h"
#include <utility>
#include <queue>
#include <systemc>
#include <tlm>
#include <utility>
namespace DRAMSys
{

View File

@@ -44,10 +44,10 @@ namespace DRAMSys
class RespQueueIF
{
protected:
RespQueueIF(const RespQueueIF &) = default;
RespQueueIF(RespQueueIF &&) = default;
RespQueueIF &operator=(const RespQueueIF &) = default;
RespQueueIF &operator=(RespQueueIF &&) = default;
RespQueueIF(const RespQueueIF&) = default;
RespQueueIF(RespQueueIF&&) = default;
RespQueueIF& operator=(const RespQueueIF&) = default;
RespQueueIF& operator=(RespQueueIF&&) = default;
public:
RespQueueIF() = default;

View File

@@ -41,8 +41,8 @@ using namespace tlm;
namespace DRAMSys
{
BufferCounterBankwise::BufferCounterBankwise(unsigned requestBufferSize, unsigned numberOfBanks)
: requestBufferSize(requestBufferSize)
BufferCounterBankwise::BufferCounterBankwise(unsigned requestBufferSize, unsigned numberOfBanks) :
requestBufferSize(requestBufferSize)
{
numRequestsOnBank = std::vector<unsigned>(numberOfBanks, 0);
}

View File

@@ -37,8 +37,8 @@
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
#include <vector>
#include <tlm>
#include <vector>
namespace DRAMSys
{

View File

@@ -35,8 +35,8 @@
#ifndef BUFFERCOUNTERIF_H
#define BUFFERCOUNTERIF_H
#include <vector>
#include <tlm>
#include <vector>
namespace DRAMSys
{
@@ -44,10 +44,10 @@ namespace DRAMSys
class BufferCounterIF
{
protected:
BufferCounterIF(const BufferCounterIF &) = default;
BufferCounterIF(BufferCounterIF &&) = default;
BufferCounterIF &operator=(const BufferCounterIF &) = default;
BufferCounterIF &operator=(BufferCounterIF &&) = default;
BufferCounterIF(const BufferCounterIF&) = default;
BufferCounterIF(BufferCounterIF&&) = default;
BufferCounterIF& operator=(const BufferCounterIF&) = default;
BufferCounterIF& operator=(BufferCounterIF&&) = default;
public:
BufferCounterIF() = default;

View File

@@ -39,15 +39,16 @@ using namespace tlm;
namespace DRAMSys
{
BufferCounterReadWrite::BufferCounterReadWrite(unsigned requestBufferSize)
: requestBufferSize(requestBufferSize)
BufferCounterReadWrite::BufferCounterReadWrite(unsigned requestBufferSize) :
requestBufferSize(requestBufferSize)
{
numReadWriteRequests = std::vector<unsigned>(2);
}
bool BufferCounterReadWrite::hasBufferSpace() const
{
return (numReadWriteRequests[0] < requestBufferSize && numReadWriteRequests[1] < requestBufferSize);
return (numReadWriteRequests[0] < requestBufferSize &&
numReadWriteRequests[1] < requestBufferSize);
}
void BufferCounterReadWrite::storeRequest(const tlm_generic_payload& trans)

View File

@@ -37,8 +37,8 @@
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
#include <vector>
#include <tlm>
#include <vector>
namespace DRAMSys
{

View File

@@ -39,8 +39,8 @@ using namespace tlm;
namespace DRAMSys
{
BufferCounterShared::BufferCounterShared(unsigned requestBufferSize)
: requestBufferSize(requestBufferSize)
BufferCounterShared::BufferCounterShared(unsigned requestBufferSize) :
requestBufferSize(requestBufferSize)
{
numRequests = std::vector<unsigned>(1);
}

View File

@@ -37,8 +37,8 @@
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
#include <vector>
#include <tlm>
#include <vector>
namespace DRAMSys
{

View File

@@ -45,10 +45,12 @@ namespace DRAMSys
SchedulerFifo::SchedulerFifo(const Configuration& config)
{
buffer = ControllerVector<Bank, std::deque<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
buffer =
ControllerVector<Bank, std::deque<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize, config.memSpec->banksPerChannel);
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize,
config.memSpec->banksPerChannel);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
bufferCounter = std::make_unique<BufferCounterReadWrite>(config.requestBufferSize);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)

View File

@@ -35,15 +35,15 @@
#ifndef SCHEDULERFIFO_H
#define SCHEDULERFIFO_H
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
#include "DRAMSys/common/dramExtensions.h"
#include "DRAMSys/controller/BankMachine.h"
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
#include <vector>
#include <deque>
#include <memory>
#include <tlm>
#include <vector>
namespace DRAMSys
{
@@ -55,8 +55,10 @@ public:
[[nodiscard]] bool hasBufferSpace() const override;
void storeRequest(tlm::tlm_generic_payload& payload) override;
void removeRequest(tlm::tlm_generic_payload& payload) override;
[[nodiscard]] tlm::tlm_generic_payload* getNextRequest(const BankMachine& bankMachine) const override;
[[nodiscard]] bool hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const override;
[[nodiscard]] tlm::tlm_generic_payload*
getNextRequest(const BankMachine& bankMachine) const override;
[[nodiscard]] bool
hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const override;
[[nodiscard]] bool hasFurtherRequest(Bank bank, tlm::tlm_command command) const override;
[[nodiscard]] const std::vector<unsigned>& getBufferDepth() const override;

View File

@@ -45,10 +45,12 @@ namespace DRAMSys
SchedulerFrFcfs::SchedulerFrFcfs(const Configuration& config)
{
buffer = ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
buffer =
ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize, config.memSpec->banksPerChannel);
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize,
config.memSpec->banksPerChannel);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
bufferCounter = std::make_unique<BufferCounterReadWrite>(config.requestBufferSize);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
@@ -101,7 +103,9 @@ tlm_generic_payload* SchedulerFrFcfs::getNextRequest(const BankMachine& bankMach
return nullptr;
}
bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]] tlm_command command) const
bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank,
Row row,
[[maybe_unused]] tlm_command command) const
{
unsigned rowHitCounter = 0;
for (auto* it : buffer[bank])

View File

@@ -35,15 +35,15 @@
#ifndef SCHEDULERFRFCFS_H
#define SCHEDULERFRFCFS_H
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
#include "DRAMSys/common/dramExtensions.h"
#include "DRAMSys/controller/BankMachine.h"
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
#include <vector>
#include <list>
#include <memory>
#include <tlm>
#include <vector>
namespace DRAMSys
{
@@ -55,8 +55,10 @@ public:
[[nodiscard]] bool hasBufferSpace() const override;
void storeRequest(tlm::tlm_generic_payload& payload) override;
void removeRequest(tlm::tlm_generic_payload& payload) override;
[[nodiscard]] tlm::tlm_generic_payload* getNextRequest(const BankMachine& bankMachine) const override;
[[nodiscard]] bool hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const override;
[[nodiscard]] tlm::tlm_generic_payload*
getNextRequest(const BankMachine& bankMachine) const override;
[[nodiscard]] bool
hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const override;
[[nodiscard]] bool hasFurtherRequest(Bank bank, tlm::tlm_command command) const override;
[[nodiscard]] const std::vector<unsigned>& getBufferDepth() const override;

View File

@@ -45,10 +45,12 @@ namespace DRAMSys
SchedulerFrFcfsGrp::SchedulerFrFcfsGrp(const Configuration& config)
{
buffer = ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
buffer =
ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize, config.memSpec->banksPerChannel);
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize,
config.memSpec->banksPerChannel);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
bufferCounter = std::make_unique<BufferCounterReadWrite>(config.requestBufferSize);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
@@ -90,8 +92,8 @@ tlm_generic_payload* SchedulerFrFcfsGrp::getNextRequest(const BankMachine& bankM
{
// Filter all row hits
Row openRow = bankMachine.getOpenRow();
std::list<tlm_generic_payload *> rowHits;
for (auto *it : buffer[bank])
std::list<tlm_generic_payload*> rowHits;
for (auto* it : buffer[bank])
{
if (ControllerExtension::getRow(*it) == openRow)
rowHits.push_back(it);
@@ -126,10 +128,12 @@ tlm_generic_payload* SchedulerFrFcfsGrp::getNextRequest(const BankMachine& bankM
return nullptr;
}
bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]] tlm_command command) const
bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank,
Row row,
[[maybe_unused]] tlm_command command) const
{
unsigned rowHitCounter = 0;
for (auto *it : buffer[bank])
for (auto* it : buffer[bank])
{
if (ControllerExtension::getRow(*it) == row)
{

View File

@@ -35,15 +35,15 @@
#ifndef SCHEDULERFRFCFSGRP_H
#define SCHEDULERFRFCFSGRP_H
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
#include "DRAMSys/common/dramExtensions.h"
#include "DRAMSys/controller/BankMachine.h"
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
#include <vector>
#include <list>
#include <memory>
#include <tlm>
#include <vector>
namespace DRAMSys
{
@@ -55,13 +55,15 @@ public:
[[nodiscard]] bool hasBufferSpace() const override;
void storeRequest(tlm::tlm_generic_payload& payload) override;
void removeRequest(tlm::tlm_generic_payload& payload) override;
[[nodiscard]] tlm::tlm_generic_payload* getNextRequest(const BankMachine& bankMachine) const override;
[[nodiscard]] bool hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const override;
[[nodiscard]] tlm::tlm_generic_payload*
getNextRequest(const BankMachine& bankMachine) const override;
[[nodiscard]] bool
hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const override;
[[nodiscard]] bool hasFurtherRequest(Bank bank, tlm::tlm_command command) const override;
[[nodiscard]] const std::vector<unsigned>& getBufferDepth() const override;
private:
ControllerVector<Bank, std::list<tlm::tlm_generic_payload *>> buffer;
ControllerVector<Bank, std::list<tlm::tlm_generic_payload*>> buffer;
tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND;
std::unique_ptr<BufferCounterIF> bufferCounter;
};

View File

@@ -45,11 +45,14 @@ namespace DRAMSys
SchedulerGrpFrFcfs::SchedulerGrpFrFcfs(const Configuration& config)
{
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*>>(config.memSpec->banksPerChannel);
writeBuffer =
ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize, config.memSpec->banksPerChannel);
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize,
config.memSpec->banksPerChannel);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
bufferCounter = std::make_unique<BufferCounterReadWrite>(config.requestBufferSize);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
@@ -98,7 +101,7 @@ tlm_generic_payload* SchedulerGrpFrFcfs::getNextRequest(const BankMachine& bankM
{
// Search for read row hit
Row openRow = bankMachine.getOpenRow();
for (auto *it : readBuffer[bank])
for (auto* it : readBuffer[bank])
{
if (ControllerExtension::getRow(*it) == openRow)
return it;
@@ -113,7 +116,7 @@ tlm_generic_payload* SchedulerGrpFrFcfs::getNextRequest(const BankMachine& bankM
{
// Search for write row hit
Row openRow = bankMachine.getOpenRow();
for (auto *it : writeBuffer[bank])
for (auto* it : writeBuffer[bank])
{
if (ControllerExtension::getRow(*it) == openRow)
return it;
@@ -131,7 +134,7 @@ tlm_generic_payload* SchedulerGrpFrFcfs::getNextRequest(const BankMachine& bankM
{
// Search for write row hit
Row openRow = bankMachine.getOpenRow();
for (auto *it : writeBuffer[bank])
for (auto* it : writeBuffer[bank])
{
if (ControllerExtension::getRow(*it) == openRow)
return it;
@@ -146,7 +149,7 @@ tlm_generic_payload* SchedulerGrpFrFcfs::getNextRequest(const BankMachine& bankM
{
// Search for read row hit
Row openRow = bankMachine.getOpenRow();
for (auto *it : readBuffer[bank])
for (auto* it : readBuffer[bank])
{
if (ControllerExtension::getRow(*it) == openRow)
return it;
@@ -164,7 +167,7 @@ bool SchedulerGrpFrFcfs::hasFurtherRowHit(Bank bank, Row row, tlm_command comman
unsigned rowHitCounter = 0;
if (command == tlm::TLM_READ_COMMAND)
{
for (auto *it : readBuffer[bank])
for (auto* it : readBuffer[bank])
{
if (ControllerExtension::getRow(*it) == row)
{
@@ -197,7 +200,6 @@ bool SchedulerGrpFrFcfs::hasFurtherRequest(Bank bank, tlm_command command) const
}
return writeBuffer[bank].size() >= 2;
}
const std::vector<unsigned>& SchedulerGrpFrFcfs::getBufferDepth() const

View File

@@ -35,15 +35,15 @@
#ifndef SCHEDULERGRPFRFCFS_H
#define SCHEDULERGRPFRFCFS_H
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
#include "DRAMSys/common/dramExtensions.h"
#include "DRAMSys/controller/BankMachine.h"
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
#include <vector>
#include <list>
#include <memory>
#include <tlm>
#include <vector>
namespace DRAMSys
{
@@ -55,8 +55,10 @@ public:
[[nodiscard]] bool hasBufferSpace() const override;
void storeRequest(tlm::tlm_generic_payload& payload) override;
void removeRequest(tlm::tlm_generic_payload& payload) override;
[[nodiscard]] tlm::tlm_generic_payload* getNextRequest(const BankMachine& bankMachine) const override;
[[nodiscard]] bool hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const override;
[[nodiscard]] tlm::tlm_generic_payload*
getNextRequest(const BankMachine& bankMachine) const override;
[[nodiscard]] bool
hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const override;
[[nodiscard]] bool hasFurtherRequest(Bank bank, tlm::tlm_command command) const override;
[[nodiscard]] const std::vector<unsigned>& getBufferDepth() const override;

View File

@@ -43,14 +43,18 @@ using namespace tlm;
namespace DRAMSys
{
SchedulerGrpFrFcfsWm::SchedulerGrpFrFcfsWm(const Configuration& config)
: lowWatermark(config.lowWatermark), highWatermark(config.highWatermark)
SchedulerGrpFrFcfsWm::SchedulerGrpFrFcfsWm(const Configuration& config) :
lowWatermark(config.lowWatermark),
highWatermark(config.highWatermark)
{
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*>>(config.memSpec->banksPerChannel);
writeBuffer =
ControllerVector<Bank, std::list<tlm_generic_payload*>>(config.memSpec->banksPerChannel);
if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise)
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize, config.memSpec->banksPerChannel);
bufferCounter = std::make_unique<BufferCounterBankwise>(config.requestBufferSize,
config.memSpec->banksPerChannel);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite)
bufferCounter = std::make_unique<BufferCounterReadWrite>(config.requestBufferSize);
else if (config.schedulerBuffer == Configuration::SchedulerBuffer::Shared)
@@ -102,7 +106,7 @@ tlm_generic_payload* SchedulerGrpFrFcfsWm::getNextRequest(const BankMachine& ban
{
// Search for read row hit
Row openRow = bankMachine.getOpenRow();
for (auto *it : readBuffer[bank])
for (auto* it : readBuffer[bank])
{
if (ControllerExtension::getRow(*it) == openRow)
return it;
@@ -133,7 +137,9 @@ tlm_generic_payload* SchedulerGrpFrFcfsWm::getNextRequest(const BankMachine& ban
return nullptr;
}
bool SchedulerGrpFrFcfsWm::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]] tlm::tlm_command command) const
bool SchedulerGrpFrFcfsWm::hasFurtherRowHit(Bank bank,
Row row,
[[maybe_unused]] tlm::tlm_command command) const
{
unsigned rowHitCounter = 0;
if (!writeMode)
@@ -163,7 +169,8 @@ bool SchedulerGrpFrFcfsWm::hasFurtherRowHit(Bank bank, Row row, [[maybe_unused]]
return false;
}
bool SchedulerGrpFrFcfsWm::hasFurtherRequest(Bank bank, [[maybe_unused]] tlm::tlm_command command) const
bool SchedulerGrpFrFcfsWm::hasFurtherRequest(Bank bank,
[[maybe_unused]] tlm::tlm_command command) const
{
if (!writeMode)
{
@@ -182,12 +189,14 @@ void SchedulerGrpFrFcfsWm::evaluateWriteMode()
{
if (writeMode)
{
if (bufferCounter->getNumWriteRequests() <= lowWatermark && bufferCounter->getNumReadRequests() != 0)
if (bufferCounter->getNumWriteRequests() <= lowWatermark &&
bufferCounter->getNumReadRequests() != 0)
writeMode = false;
}
else
{
if (bufferCounter->getNumWriteRequests() > highWatermark || bufferCounter->getNumReadRequests() == 0)
if (bufferCounter->getNumWriteRequests() > highWatermark ||
bufferCounter->getNumReadRequests() == 0)
writeMode = true;
}
}

View File

@@ -35,16 +35,16 @@
#ifndef SCHEDULERGRPFRFCFSWM_H
#define SCHEDULERGRPFRFCFSWM_H
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
#include "DRAMSys/common/dramExtensions.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/controller/BankMachine.h"
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/controller/scheduler/SchedulerIF.h"
#include <vector>
#include <list>
#include <memory>
#include <tlm>
#include <vector>
namespace DRAMSys
{
@@ -56,8 +56,10 @@ public:
[[nodiscard]] bool hasBufferSpace() const override;
void storeRequest(tlm::tlm_generic_payload& payload) override;
void removeRequest(tlm::tlm_generic_payload& payload) override;
[[nodiscard]] tlm::tlm_generic_payload* getNextRequest(const BankMachine& bankMachine) const override;
[[nodiscard]] bool hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const override;
[[nodiscard]] tlm::tlm_generic_payload*
getNextRequest(const BankMachine& bankMachine) const override;
[[nodiscard]] bool
hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const override;
[[nodiscard]] bool hasFurtherRequest(Bank bank, tlm::tlm_command command) const override;
[[nodiscard]] const std::vector<unsigned>& getBufferDepth() const override;

View File

@@ -37,8 +37,8 @@
#include "DRAMSys/common/dramExtensions.h"
#include <vector>
#include <tlm>
#include <vector>
namespace DRAMSys
{
@@ -48,10 +48,10 @@ class BankMachine;
class SchedulerIF
{
protected:
SchedulerIF(const SchedulerIF &) = default;
SchedulerIF(SchedulerIF &&) = default;
SchedulerIF &operator=(const SchedulerIF &) = default;
SchedulerIF &operator=(SchedulerIF &&) = default;
SchedulerIF(const SchedulerIF&) = default;
SchedulerIF(SchedulerIF&&) = default;
SchedulerIF& operator=(const SchedulerIF&) = default;
SchedulerIF& operator=(SchedulerIF&&) = default;
public:
SchedulerIF() = default;
@@ -60,8 +60,10 @@ public:
[[nodiscard]] virtual bool hasBufferSpace() const = 0;
virtual void storeRequest(tlm::tlm_generic_payload& payload) = 0;
virtual void removeRequest(tlm::tlm_generic_payload& payload) = 0;
[[nodiscard]] virtual tlm::tlm_generic_payload* getNextRequest(const BankMachine& bankMachine) const = 0;
[[nodiscard]] virtual bool hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const = 0;
[[nodiscard]] virtual tlm::tlm_generic_payload*
getNextRequest(const BankMachine& bankMachine) const = 0;
[[nodiscard]] virtual bool
hasFurtherRowHit(Bank bank, Row row, tlm::tlm_command command) const = 0;
[[nodiscard]] virtual bool hasFurtherRequest(Bank bank, tlm::tlm_command command) const = 0;
[[nodiscard]] virtual const std::vector<unsigned>& getBufferDepth() const = 0;
};

View File

@@ -39,30 +39,32 @@
#include "AddressDecoder.h"
#include "DRAMSys/configuration/Configuration.h"
#include <cmath>
#include <iostream>
#include <iomanip>
#include <bitset>
#include <cmath>
#include <iomanip>
#include <iostream>
namespace DRAMSys
{
AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping &addressMapping, const MemSpec &memSpec)
AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping& addressMapping,
const MemSpec& memSpec)
{
if (const auto &channelBits = addressMapping.CHANNEL_BIT)
if (const auto& channelBits = addressMapping.CHANNEL_BIT)
{
std::copy(channelBits->begin(), channelBits->end(), std::back_inserter(vChannelBits));
}
if (const auto &rankBits = addressMapping.RANK_BIT)
if (const auto& rankBits = addressMapping.RANK_BIT)
{
std::copy(rankBits->begin(), rankBits->end(), std::back_inserter(vRankBits));
}
// HBM pseudo channels are internally modelled as ranks
if (const auto &pseudoChannelBits = addressMapping.PSEUDOCHANNEL_BIT)
if (const auto& pseudoChannelBits = addressMapping.PSEUDOCHANNEL_BIT)
{
std::copy(pseudoChannelBits->begin(), pseudoChannelBits->end(), std::back_inserter(vRankBits));
std::copy(
pseudoChannelBits->begin(), pseudoChannelBits->end(), std::back_inserter(vRankBits));
}
if (const auto& bankGroupBits = addressMapping.BANKGROUP_BIT)
@@ -70,12 +72,12 @@ AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping &addressMap
std::copy(bankGroupBits->begin(), bankGroupBits->end(), std::back_inserter(vBankGroupBits));
}
if (const auto &byteBits = addressMapping.BYTE_BIT)
if (const auto& byteBits = addressMapping.BYTE_BIT)
{
std::copy(byteBits->begin(), byteBits->end(), std::back_inserter(vByteBits));
}
if (const auto &xorBits = addressMapping.XOR)
if (const auto& xorBits = addressMapping.XOR)
{
for (const auto& xorBit : *xorBits)
{
@@ -83,17 +85,17 @@ AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping &addressMap
}
}
if (const auto &bankBits = addressMapping.BANK_BIT)
if (const auto& bankBits = addressMapping.BANK_BIT)
{
std::copy(bankBits->begin(), bankBits->end(), std::back_inserter(vBankBits));
}
if (const auto &rowBits = addressMapping.ROW_BIT)
if (const auto& rowBits = addressMapping.ROW_BIT)
{
std::copy(rowBits->begin(), rowBits->end(), std::back_inserter(vRowBits));
}
if (const auto &columnBits = addressMapping.COLUMN_BIT)
if (const auto& columnBits = addressMapping.COLUMN_BIT)
{
std::copy(columnBits->begin(), columnBits->end(), std::back_inserter(vColumnBits));
}
@@ -106,20 +108,20 @@ AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping &addressMap
unsigned columns = std::lround(std::pow(2.0, vColumnBits.size()));
unsigned bytes = std::lround(std::pow(2.0, vByteBits.size()));
maximumAddress = static_cast<uint64_t>(bytes) * columns * rows * banks
* bankGroups * ranks * channels - 1;
maximumAddress =
static_cast<uint64_t>(bytes) * columns * rows * banks * bankGroups * ranks * channels - 1;
auto totalAddressBits = static_cast<unsigned>(std::log2(maximumAddress));
for (unsigned bitPosition = 0; bitPosition < totalAddressBits; bitPosition++)
{
if (std::count(vChannelBits.begin(), vChannelBits.end(), bitPosition)
+ std::count(vRankBits.begin(), vRankBits.end(), bitPosition)
+ std::count(vBankGroupBits.begin(), vBankGroupBits.end(), bitPosition)
+ std::count(vBankBits.begin(), vBankBits.end(), bitPosition)
+ std::count(vRowBits.begin(), vRowBits.end(), bitPosition)
+ std::count(vColumnBits.begin(), vColumnBits.end(), bitPosition)
+ std::count(vByteBits.begin(), vByteBits.end(), bitPosition)
!= 1)
if (std::count(vChannelBits.begin(), vChannelBits.end(), bitPosition) +
std::count(vRankBits.begin(), vRankBits.end(), bitPosition) +
std::count(vBankGroupBits.begin(), vBankGroupBits.end(), bitPosition) +
std::count(vBankBits.begin(), vBankBits.end(), bitPosition) +
std::count(vRowBits.begin(), vRowBits.end(), bitPosition) +
std::count(vColumnBits.begin(), vColumnBits.end(), bitPosition) +
std::count(vByteBits.begin(), vByteBits.end(), bitPosition) !=
1)
SC_REPORT_FATAL("AddressDecoder", "Not all address bits occur exactly once");
}
@@ -133,7 +135,9 @@ AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping &addressMap
auto maxBurstLengthBits = static_cast<unsigned>(std::log2(memSpec.maxBurstLength));
for (unsigned bitPosition = highestByteBit + 1; bitPosition < highestByteBit + 1 + maxBurstLengthBits; bitPosition++)
for (unsigned bitPosition = highestByteBit + 1;
bitPosition < highestByteBit + 1 + maxBurstLengthBits;
bitPosition++)
{
if (std::find(vColumnBits.begin(), vColumnBits.end(), bitPosition) == vColumnBits.end())
SC_REPORT_FATAL("AddressDecoder", "No continuous column bits for maximum burst length");
@@ -145,24 +149,30 @@ AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping &addressMap
banksPerGroup = banks;
banks = banksPerGroup * bankGroups;
if (memSpec.numberOfChannels != channels || memSpec.ranksPerChannel != ranks
|| memSpec.bankGroupsPerChannel != bankGroups || memSpec.banksPerChannel != banks
|| memSpec.rowsPerBank != rows || memSpec.columnsPerRow != columns
|| memSpec.devicesPerRank * memSpec.bitWidth != bytes * 8)
if (memSpec.numberOfChannels != channels || memSpec.ranksPerChannel != ranks ||
memSpec.bankGroupsPerChannel != bankGroups || memSpec.banksPerChannel != banks ||
memSpec.rowsPerBank != rows || memSpec.columnsPerRow != columns ||
memSpec.devicesPerRank * memSpec.bitWidth != bytes * 8)
SC_REPORT_FATAL("AddressDecoder", "Memspec and address mapping do not match");
}
DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr) const
{
if (encAddr > maximumAddress)
SC_REPORT_WARNING("AddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str());
SC_REPORT_WARNING("AddressDecoder",
("Address " + std::to_string(encAddr) +
" out of range (maximum address is " + std::to_string(maximumAddress) +
")")
.c_str());
// Apply XOR
// For each used xor:
// Get the first bit and second bit. Apply a bitwise xor operator and save it back to the first bit.
for (const auto &it : vXor)
// Get the first bit and second bit. Apply a bitwise xor operator and save it back to the
// first bit.
for (const auto& it : vXor)
{
uint64_t xoredBit = (((encAddr >> it.first) & UINT64_C(1)) ^ ((encAddr >> it.second) & UINT64_C(1)));
uint64_t xoredBit =
(((encAddr >> it.first) & UINT64_C(1)) ^ ((encAddr >> it.second) & UINT64_C(1)));
encAddr &= ~(UINT64_C(1) << it.first);
encAddr |= xoredBit << it.first;
}
@@ -199,14 +209,20 @@ DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr) const
unsigned AddressDecoder::decodeChannel(uint64_t encAddr) const
{
if (encAddr > maximumAddress)
SC_REPORT_WARNING("AddressDecoder", ("Address " + std::to_string(encAddr) + " out of range (maximum address is " + std::to_string(maximumAddress) + ")").c_str());
SC_REPORT_WARNING("AddressDecoder",
("Address " + std::to_string(encAddr) +
" out of range (maximum address is " + std::to_string(maximumAddress) +
")")
.c_str());
// Apply XOR
// For each used xor:
// Get the first bit and second bit. Apply a bitwise xor operator and save it back to the first bit.
for (const auto &it : vXor)
// Get the first bit and second bit. Apply a bitwise xor operator and save it back to the
// first bit.
for (const auto& it : vXor)
{
uint64_t xoredBit = (((encAddr >> it.first) & UINT64_C(1)) ^ ((encAddr >> it.second) & UINT64_C(1)));
uint64_t xoredBit =
(((encAddr >> it.first) & UINT64_C(1)) ^ ((encAddr >> it.second) & UINT64_C(1)));
encAddr &= ~(UINT64_C(1) << it.first);
encAddr |= xoredBit << it.first;
}
@@ -253,7 +269,6 @@ uint64_t AddressDecoder::encodeAddress(DecodedAddress decodedAddress) const
return address;
}
void AddressDecoder::print() const
{
std::cout << headline << std::endl;
@@ -262,79 +277,93 @@ void AddressDecoder::print() const
for (int it = static_cast<int>(vChannelBits.size() - 1); it >= 0; it--)
{
uint64_t addressBits = (UINT64_C(1) << vChannelBits[static_cast<std::vector<unsigned>::size_type>(it)]);
uint64_t addressBits =
(UINT64_C(1) << vChannelBits[static_cast<std::vector<unsigned>::size_type>(it)]);
for (auto it2 : vXor)
{
if (it2.first == vChannelBits[static_cast<std::vector<unsigned>::size_type>(it)])
addressBits |= (UINT64_C(1) << it2.second);
}
std::cout << " Ch " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
std::cout << " Ch " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
<< std::endl;
}
for (int it = static_cast<int>(vRankBits.size() - 1); it >= 0; it--)
{
uint64_t addressBits = (UINT64_C(1) << vRankBits[static_cast<std::vector<unsigned>::size_type>(it)]);
uint64_t addressBits =
(UINT64_C(1) << vRankBits[static_cast<std::vector<unsigned>::size_type>(it)]);
for (auto it2 : vXor)
{
if (it2.first == vRankBits[static_cast<std::vector<unsigned>::size_type>(it)])
addressBits |= (UINT64_C(1) << it2.second);
}
std::cout << " Ra " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
std::cout << " Ra " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
<< std::endl;
}
for (int it = static_cast<int>(vBankGroupBits.size() - 1); it >= 0; it--)
{
uint64_t addressBits = (UINT64_C(1) << vBankGroupBits[static_cast<std::vector<unsigned>::size_type>(it)]);
uint64_t addressBits =
(UINT64_C(1) << vBankGroupBits[static_cast<std::vector<unsigned>::size_type>(it)]);
for (auto it2 : vXor)
{
if (it2.first == vBankGroupBits[static_cast<std::vector<unsigned>::size_type>(it)])
addressBits |= (UINT64_C(1) << it2.second);
}
std::cout << " Bg " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
std::cout << " Bg " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
<< std::endl;
}
for (int it = static_cast<int>(vBankBits.size() - 1); it >= 0; it--)
{
uint64_t addressBits = (UINT64_C(1) << vBankBits[static_cast<std::vector<unsigned>::size_type>(it)]);
uint64_t addressBits =
(UINT64_C(1) << vBankBits[static_cast<std::vector<unsigned>::size_type>(it)]);
for (auto it2 : vXor)
{
if (it2.first == vBankBits[static_cast<std::vector<unsigned>::size_type>(it)])
addressBits |= (UINT64_C(1) << it2.second);
}
std::cout << " Ba " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
std::cout << " Ba " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
<< std::endl;
}
for (int it = static_cast<int>(vRowBits.size() - 1); it >= 0; it--)
{
uint64_t addressBits = (UINT64_C(1) << vRowBits[static_cast<std::vector<unsigned>::size_type>(it)]);
uint64_t addressBits =
(UINT64_C(1) << vRowBits[static_cast<std::vector<unsigned>::size_type>(it)]);
for (auto it2 : vXor)
{
if (it2.first == vRowBits[static_cast<std::vector<unsigned>::size_type>(it)])
addressBits |= (UINT64_C(1) << it2.second);
}
std::cout << " Ro " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
std::cout << " Ro " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
<< std::endl;
}
for (int it = static_cast<int>(vColumnBits.size() - 1); it >= 0; it--)
{
uint64_t addressBits = (UINT64_C(1) << vColumnBits[static_cast<std::vector<unsigned>::size_type>(it)]);
uint64_t addressBits =
(UINT64_C(1) << vColumnBits[static_cast<std::vector<unsigned>::size_type>(it)]);
for (auto it2 : vXor)
{
if (it2.first == vColumnBits[static_cast<std::vector<unsigned>::size_type>(it)])
addressBits |= (UINT64_C(1) << it2.second);
}
std::cout << " Co " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
std::cout << " Co " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
<< std::endl;
}
for (int it = static_cast<int>(vByteBits.size() - 1); it >= 0; it--)
{
uint64_t addressBits = (UINT64_C(1) << vByteBits[static_cast<std::vector<unsigned>::size_type>(it)]);
uint64_t addressBits =
(UINT64_C(1) << vByteBits[static_cast<std::vector<unsigned>::size_type>(it)]);
for (auto it2 : vXor)
{
if (it2.first == vByteBits[static_cast<std::vector<unsigned>::size_type>(it)])
addressBits |= (UINT64_C(1) << it2.second);
}
std::cout << " By " << std::setw(2) << it << ": " << std::bitset<64>(addressBits) << std::endl;
std::cout << " By " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
<< std::endl;
}
std::cout << std::endl;

View File

@@ -42,20 +42,30 @@
#include "DRAMSys/config/DRAMSysConfiguration.h"
#include "DRAMSys/configuration/Configuration.h"
#include <vector>
#include <utility>
#include <vector>
namespace DRAMSys
{
struct DecodedAddress
{
DecodedAddress(unsigned channel, unsigned rank,
unsigned bankgroup, unsigned bank,
unsigned row, unsigned column, unsigned bytes)
: channel(channel), rank(rank),
bankgroup(bankgroup), bank(bank),
row(row), column(column), byte(bytes) {}
DecodedAddress(unsigned channel,
unsigned rank,
unsigned bankgroup,
unsigned bank,
unsigned row,
unsigned column,
unsigned bytes) :
channel(channel),
rank(rank),
bankgroup(bankgroup),
bank(bank),
row(row),
column(column),
byte(bytes)
{
}
DecodedAddress() = default;
@@ -71,7 +81,7 @@ struct DecodedAddress
class AddressDecoder
{
public:
AddressDecoder(const DRAMSys::Config::AddressMapping &addressMapping, const MemSpec &memSpec);
AddressDecoder(const DRAMSys::Config::AddressMapping& addressMapping, const MemSpec& memSpec);
[[nodiscard]] DecodedAddress decodeAddress(uint64_t encAddr) const;
[[nodiscard]] unsigned decodeChannel(uint64_t encAddr) const;
[[nodiscard]] uint64_t encodeAddress(DecodedAddress decodedAddress) const;
@@ -83,7 +93,8 @@ private:
uint64_t maximumAddress;
// This container stores for each used xor gate a pair of address bits, the first bit is overwritten with the result
// This container stores for each used xor gate a pair of address bits, the first bit is
// overwritten with the result
std::vector<std::pair<unsigned, unsigned>> vXor;
std::vector<unsigned> vChannelBits;
std::vector<unsigned> vRankBits;

View File

@@ -39,9 +39,9 @@
#include "Arbiter.h"
#include "DRAMSys/simulation/AddressDecoder.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/common/DebugManager.h"
#include "DRAMSys/configuration/Configuration.h"
#include "DRAMSys/simulation/AddressDecoder.h"
#include "DRAMSys/config/DRAMSysConfiguration.h"
@@ -51,9 +51,12 @@ using namespace tlm;
namespace DRAMSys
{
Arbiter::Arbiter(const sc_module_name& name, const Configuration& config,
Arbiter::Arbiter(const sc_module_name& name,
const Configuration& config,
const AddressDecoder& addressDecoder) :
sc_module(name), addressDecoder(addressDecoder), payloadEventQueue(this, &Arbiter::peqCallback),
sc_module(name),
addressDecoder(addressDecoder),
payloadEventQueue(this, &Arbiter::peqCallback),
tCK(config.memSpec->tCK),
arbitrationDelayFw(config.arbitrationDelayFw),
arbitrationDelayBw(config.arbitrationDelayBw),
@@ -66,19 +69,28 @@ Arbiter::Arbiter(const sc_module_name& name, const Configuration& config,
tSocket.register_transport_dbg(this, &Arbiter::transport_dbg);
}
ArbiterSimple::ArbiterSimple(const sc_module_name& name, const Configuration& config,
ArbiterSimple::ArbiterSimple(const sc_module_name& name,
const Configuration& config,
const AddressDecoder& addressDecoder) :
Arbiter(name, config, addressDecoder) {}
Arbiter(name, config, addressDecoder)
{
}
ArbiterFifo::ArbiterFifo(const sc_module_name& name, const Configuration& config,
ArbiterFifo::ArbiterFifo(const sc_module_name& name,
const Configuration& config,
const AddressDecoder& addressDecoder) :
Arbiter(name, config, addressDecoder),
maxActiveTransactionsPerThread(config.maxActiveTransactions) {}
Arbiter(name, config, addressDecoder),
maxActiveTransactionsPerThread(config.maxActiveTransactions)
{
}
ArbiterReorder::ArbiterReorder(const sc_module_name& name, const Configuration& config,
ArbiterReorder::ArbiterReorder(const sc_module_name& name,
const Configuration& config,
const AddressDecoder& addressDecoder) :
Arbiter(name, config, addressDecoder),
maxActiveTransactions(config.maxActiveTransactions) {}
maxActiveTransactions(config.maxActiveTransactions)
{
}
void Arbiter::end_of_elaboration()
{
@@ -89,7 +101,7 @@ void Arbiter::end_of_elaboration()
// channel side
channelIsBusy = ControllerVector<Channel, bool>(iSocket.size(), false);
pendingRequestsOnChannel = ControllerVector<Channel, std::queue<tlm_generic_payload*>>(
iSocket.size(), std::queue<tlm_generic_payload*>());
iSocket.size(), std::queue<tlm_generic_payload*>());
nextChannelPayloadIDToAppend = ControllerVector<Channel, std::uint64_t>(iSocket.size(), 1);
}
@@ -99,7 +111,7 @@ void ArbiterSimple::end_of_elaboration()
// initiator side
pendingResponsesOnThread = ControllerVector<Thread, std::queue<tlm_generic_payload*>>(
tSocket.size(), std::queue<tlm_generic_payload*>());
tSocket.size(), std::queue<tlm_generic_payload*>());
}
void ArbiterFifo::end_of_elaboration()
@@ -108,9 +120,10 @@ void ArbiterFifo::end_of_elaboration()
// initiator side
activeTransactionsOnThread = ControllerVector<Thread, unsigned int>(tSocket.size(), 0);
outstandingEndReqOnThread = ControllerVector<Thread, tlm_generic_payload*>(tSocket.size(), nullptr);
outstandingEndReqOnThread =
ControllerVector<Thread, tlm_generic_payload*>(tSocket.size(), nullptr);
pendingResponsesOnThread = ControllerVector<Thread, std::queue<tlm_generic_payload*>>(
tSocket.size(), std::queue<tlm_generic_payload*>());
tSocket.size(), std::queue<tlm_generic_payload*>());
lastEndReqOnChannel = ControllerVector<Channel, sc_time>(iSocket.size(), sc_max_time());
lastEndRespOnThread = ControllerVector<Thread, sc_time>(tSocket.size(), sc_max_time());
@@ -122,17 +135,19 @@ void ArbiterReorder::end_of_elaboration()
// initiator side
activeTransactionsOnThread = ControllerVector<Thread, unsigned int>(tSocket.size(), 0);
outstandingEndReqOnThread = ControllerVector<Thread, tlm_generic_payload*>(tSocket.size(), nullptr);
pendingResponsesOnThread = ControllerVector<Thread, std::set<tlm_generic_payload*, ThreadPayloadIDCompare>>
(tSocket.size(), std::set<tlm_generic_payload*, ThreadPayloadIDCompare>());
outstandingEndReqOnThread =
ControllerVector<Thread, tlm_generic_payload*>(tSocket.size(), nullptr);
pendingResponsesOnThread =
ControllerVector<Thread, std::set<tlm_generic_payload*, ThreadPayloadIDCompare>>(
tSocket.size(), std::set<tlm_generic_payload*, ThreadPayloadIDCompare>());
nextThreadPayloadIDToReturn = ControllerVector<Thread, std::uint64_t>(tSocket.size(), 1);
lastEndReqOnChannel = ControllerVector<Channel, sc_time>(iSocket.size(), sc_max_time());
lastEndRespOnThread = ControllerVector<Thread, sc_time>(tSocket.size(), sc_max_time());
}
tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload& trans,
tlm_phase& phase, sc_time& fwDelay)
tlm_sync_enum
Arbiter::nb_transport_fw(int id, tlm_generic_payload& trans, tlm_phase& phase, sc_time& fwDelay)
{
sc_time clockOffset = sc_time::from_value((sc_time_stamp() + fwDelay).value() % tCK.value());
sc_time notDelay = (clockOffset == SC_ZERO_TIME) ? fwDelay : (fwDelay + tCK - clockOffset);
@@ -145,27 +160,32 @@ tlm_sync_enum Arbiter::nb_transport_fw(int id, tlm_generic_payload& trans,
trans.set_address(adjustedAddress);
unsigned channel = addressDecoder.decodeChannel(adjustedAddress);
assert(addressDecoder.decodeChannel(adjustedAddress + trans.get_data_length() - 1) == channel);
assert(addressDecoder.decodeChannel(adjustedAddress + trans.get_data_length() - 1) ==
channel);
ArbiterExtension::setAutoExtension(trans, Thread(id), Channel(channel));
trans.acquire();
}
PRINTDEBUGMESSAGE(name(), "[fw] " + getPhaseName(phase) + " notification in " +
notDelay.to_string());
PRINTDEBUGMESSAGE(name(),
"[fw] " + getPhaseName(phase) + " notification in " + notDelay.to_string());
payloadEventQueue.notify(trans, phase, notDelay);
return TLM_ACCEPTED;
}
tlm_sync_enum Arbiter::nb_transport_bw([[maybe_unused]] int id, tlm_generic_payload& payload,
tlm_phase& phase, sc_time& bwDelay)
tlm_sync_enum Arbiter::nb_transport_bw([[maybe_unused]] int id,
tlm_generic_payload& payload,
tlm_phase& phase,
sc_time& bwDelay)
{
PRINTDEBUGMESSAGE(name(), "[bw] " + getPhaseName(phase) + " notification in " +
bwDelay.to_string());
PRINTDEBUGMESSAGE(name(),
"[bw] " + getPhaseName(phase) + " notification in " + bwDelay.to_string());
payloadEventQueue.notify(payload, phase, bwDelay);
return TLM_ACCEPTED;
}
void Arbiter::b_transport([[maybe_unused]] int id, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay)
void Arbiter::b_transport([[maybe_unused]] int id,
tlm::tlm_generic_payload& trans,
sc_core::sc_time& delay)
{
trans.set_address(trans.get_address() - addressOffset);
@@ -188,7 +208,8 @@ void ArbiterSimple::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& c
if (cbPhase == BEGIN_REQ) // from initiator
{
ArbiterExtension::setIDAndTimeOfGeneration(cbTrans, nextThreadPayloadIDToAppend[thread]++, sc_time_stamp());
ArbiterExtension::setIDAndTimeOfGeneration(
cbTrans, nextThreadPayloadIDToAppend[thread]++, sc_time_stamp());
if (!channelIsBusy[channel])
{
@@ -213,7 +234,7 @@ void ArbiterSimple::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& c
if (!pendingRequestsOnChannel[channel].empty())
{
tlm_generic_payload &tPayload = *pendingRequestsOnChannel[channel].front();
tlm_generic_payload& tPayload = *pendingRequestsOnChannel[channel].front();
pendingRequestsOnChannel[channel].pop();
tlm_phase tPhase = BEGIN_REQ;
// do not send two requests in the same cycle
@@ -231,7 +252,8 @@ void ArbiterSimple::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& c
tlm_phase tPhase = BEGIN_RESP;
sc_time tDelay = arbitrationDelayBw;
tlm_sync_enum returnValue = tSocket[static_cast<int>(thread)]->nb_transport_bw(cbTrans, tPhase, tDelay);
tlm_sync_enum returnValue =
tSocket[static_cast<int>(thread)]->nb_transport_bw(cbTrans, tPhase, tDelay);
// Early completion from initiator
if (returnValue == TLM_UPDATED)
payloadEventQueue.notify(cbTrans, tPhase, tDelay);
@@ -252,13 +274,14 @@ void ArbiterSimple::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& c
if (!pendingResponsesOnThread[thread].empty())
{
tlm_generic_payload &tPayload = *pendingResponsesOnThread[thread].front();
tlm_generic_payload& tPayload = *pendingResponsesOnThread[thread].front();
pendingResponsesOnThread[thread].pop();
tlm_phase tPhase = BEGIN_RESP;
// do not send two responses in the same cycle
sc_time tDelay = tCK + arbitrationDelayBw;
tlm_sync_enum returnValue = tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
tlm_sync_enum returnValue =
tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
// Early completion from initiator
if (returnValue == TLM_UPDATED)
payloadEventQueue.notify(tPayload, tPhase, tDelay);
@@ -281,8 +304,8 @@ void ArbiterFifo::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& cbP
{
activeTransactionsOnThread[thread]++;
ArbiterExtension::setIDAndTimeOfGeneration(cbTrans, nextThreadPayloadIDToAppend[thread]++,
sc_time_stamp());
ArbiterExtension::setIDAndTimeOfGeneration(
cbTrans, nextThreadPayloadIDToAppend[thread]++, sc_time_stamp());
tlm_phase tPhase = END_REQ;
sc_time tDelay = SC_ZERO_TIME;
@@ -300,7 +323,7 @@ void ArbiterFifo::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& cbP
if (!pendingRequestsOnChannel[channel].empty())
{
tlm_generic_payload &tPayload = *pendingRequestsOnChannel[channel].front();
tlm_generic_payload& tPayload = *pendingRequestsOnChannel[channel].front();
pendingRequestsOnChannel[channel].pop();
tlm_phase tPhase = BEGIN_REQ;
sc_time tDelay = tCK;
@@ -309,7 +332,7 @@ void ArbiterFifo::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& cbP
}
else
channelIsBusy[channel] = false;
}
}
else if (cbPhase == BEGIN_RESP) // from memory controller
{
// TODO: use early completion
@@ -329,13 +352,13 @@ void ArbiterFifo::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& cbP
if (outstandingEndReqOnThread[thread] != nullptr)
{
tlm_generic_payload &tPayload = *outstandingEndReqOnThread[thread];
tlm_generic_payload& tPayload = *outstandingEndReqOnThread[thread];
outstandingEndReqOnThread[thread] = nullptr;
tlm_phase tPhase = END_REQ;
sc_time tDelay = SC_ZERO_TIME;
ArbiterExtension::setIDAndTimeOfGeneration(tPayload, nextThreadPayloadIDToAppend[thread]++,
sc_time_stamp());
ArbiterExtension::setIDAndTimeOfGeneration(
tPayload, nextThreadPayloadIDToAppend[thread]++, sc_time_stamp());
tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
@@ -346,12 +369,13 @@ void ArbiterFifo::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& cbP
if (!pendingResponsesOnThread[thread].empty())
{
tlm_generic_payload &tPayload = *pendingResponsesOnThread[thread].front();
tlm_generic_payload& tPayload = *pendingResponsesOnThread[thread].front();
pendingResponsesOnThread[thread].pop();
tlm_phase tPhase = BEGIN_RESP;
sc_time tDelay = tCK;
tlm_sync_enum returnValue = tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
tlm_sync_enum returnValue =
tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
// Early completion from initiator
if (returnValue == TLM_UPDATED)
payloadEventQueue.notify(tPayload, tPhase, tDelay);
@@ -367,7 +391,7 @@ void ArbiterFifo::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& cbP
{
channelIsBusy[channel] = true;
tlm_generic_payload &tPayload = *pendingRequestsOnChannel[channel].front();
tlm_generic_payload& tPayload = *pendingRequestsOnChannel[channel].front();
pendingRequestsOnChannel[channel].pop();
tlm_phase tPhase = BEGIN_REQ;
sc_time tDelay = lastEndReqOnChannel[channel] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
@@ -383,12 +407,13 @@ void ArbiterFifo::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase& cbP
{
threadIsBusy[thread] = true;
tlm_generic_payload &tPayload = *pendingResponsesOnThread[thread].front();
tlm_generic_payload& tPayload = *pendingResponsesOnThread[thread].front();
pendingResponsesOnThread[thread].pop();
tlm_phase tPhase = BEGIN_RESP;
sc_time tDelay = lastEndRespOnThread[thread] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
tlm_sync_enum returnValue = tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
tlm_sync_enum returnValue =
tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
// Early completion from initiator
if (returnValue == TLM_UPDATED)
payloadEventQueue.notify(tPayload, tPhase, tDelay);
@@ -409,8 +434,8 @@ void ArbiterReorder::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase&
{
activeTransactionsOnThread[thread]++;
ArbiterExtension::setIDAndTimeOfGeneration(cbTrans, nextThreadPayloadIDToAppend[thread]++,
sc_time_stamp());
ArbiterExtension::setIDAndTimeOfGeneration(
cbTrans, nextThreadPayloadIDToAppend[thread]++, sc_time_stamp());
tlm_phase tPhase = END_REQ;
sc_time tDelay = SC_ZERO_TIME;
@@ -428,7 +453,7 @@ void ArbiterReorder::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase&
if (!pendingRequestsOnChannel[channel].empty())
{
tlm_generic_payload &tPayload = *pendingRequestsOnChannel[channel].front();
tlm_generic_payload& tPayload = *pendingRequestsOnChannel[channel].front();
pendingRequestsOnChannel[channel].pop();
tlm_phase tPhase = BEGIN_REQ;
sc_time tDelay = tCK;
@@ -456,13 +481,13 @@ void ArbiterReorder::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase&
if (outstandingEndReqOnThread[thread] != nullptr)
{
tlm_generic_payload &tPayload = *outstandingEndReqOnThread[thread];
tlm_generic_payload& tPayload = *outstandingEndReqOnThread[thread];
outstandingEndReqOnThread[thread] = nullptr;
tlm_phase tPhase = END_REQ;
sc_time tDelay = SC_ZERO_TIME;
ArbiterExtension::setIDAndTimeOfGeneration(tPayload, nextThreadPayloadIDToAppend[thread]++,
sc_time_stamp());
ArbiterExtension::setIDAndTimeOfGeneration(
tPayload, nextThreadPayloadIDToAppend[thread]++, sc_time_stamp());
tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
@@ -471,10 +496,10 @@ void ArbiterReorder::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase&
else
activeTransactionsOnThread[thread]--;
tlm_generic_payload &tPayload = **pendingResponsesOnThread[thread].begin();
tlm_generic_payload& tPayload = **pendingResponsesOnThread[thread].begin();
if (!pendingResponsesOnThread[thread].empty() &&
ArbiterExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[thread])
ArbiterExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[thread])
{
nextThreadPayloadIDToReturn[thread]++;
pendingResponsesOnThread[thread].erase(pendingResponsesOnThread[thread].begin());
@@ -482,7 +507,8 @@ void ArbiterReorder::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase&
tlm_phase tPhase = BEGIN_RESP;
sc_time tDelay = tCK;
tlm_sync_enum returnValue = tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
tlm_sync_enum returnValue =
tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
// Early completion from initiator
if (returnValue == TLM_UPDATED)
payloadEventQueue.notify(tPayload, tPhase, tDelay);
@@ -498,7 +524,7 @@ void ArbiterReorder::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase&
{
channelIsBusy[channel] = true;
tlm_generic_payload &tPayload = *pendingRequestsOnChannel[channel].front();
tlm_generic_payload& tPayload = *pendingRequestsOnChannel[channel].front();
pendingRequestsOnChannel[channel].pop();
tlm_phase tPhase = BEGIN_REQ;
sc_time tDelay = lastEndReqOnChannel[channel] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
@@ -512,18 +538,21 @@ void ArbiterReorder::peqCallback(tlm_generic_payload& cbTrans, const tlm_phase&
if (!threadIsBusy[thread])
{
tlm_generic_payload &tPayload = **pendingResponsesOnThread[thread].begin();
tlm_generic_payload& tPayload = **pendingResponsesOnThread[thread].begin();
if (ArbiterExtension::getThreadPayloadID(tPayload) == nextThreadPayloadIDToReturn[thread])
if (ArbiterExtension::getThreadPayloadID(tPayload) ==
nextThreadPayloadIDToReturn[thread])
{
threadIsBusy[thread] = true;
nextThreadPayloadIDToReturn[thread]++;
pendingResponsesOnThread[thread].erase(pendingResponsesOnThread[thread].begin());
tlm_phase tPhase = BEGIN_RESP;
sc_time tDelay = lastEndRespOnThread[thread] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
sc_time tDelay =
lastEndRespOnThread[thread] == sc_time_stamp() ? tCK : SC_ZERO_TIME;
tlm_sync_enum returnValue = tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
tlm_sync_enum returnValue =
tSocket[static_cast<int>(thread)]->nb_transport_bw(tPayload, tPhase, tDelay);
// Early completion from initiator
if (returnValue == TLM_UPDATED)
payloadEventQueue.notify(tPayload, tPhase, tDelay);

View File

@@ -40,18 +40,18 @@
#ifndef ARBITER_H
#define ARBITER_H
#include "DRAMSys/simulation/AddressDecoder.h"
#include "DRAMSys/common/dramExtensions.h"
#include "DRAMSys/simulation/AddressDecoder.h"
#include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <systemc>
#include <tlm>
#include <tlm_utils/multi_passthrough_target_socket.h>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include <tlm_utils/multi_passthrough_target_socket.h>
#include <tlm_utils/peq_with_cb_and_phase.h>
#include <vector>
namespace DRAMSys
{
@@ -66,7 +66,8 @@ public:
tlm_utils::multi_passthrough_target_socket<Arbiter> tSocket;
protected:
Arbiter(const sc_core::sc_module_name& name, const Configuration& config,
Arbiter(const sc_core::sc_module_name& name,
const Configuration& config,
const AddressDecoder& addressDecoder);
SC_HAS_PROCESS(Arbiter);
@@ -85,10 +86,14 @@ protected:
ControllerVector<Thread, std::uint64_t> nextThreadPayloadIDToAppend;
ControllerVector<Channel, std::uint64_t> nextChannelPayloadIDToAppend;
tlm::tlm_sync_enum nb_transport_fw(int id, tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase, sc_core::sc_time& fwDelay);
tlm::tlm_sync_enum nb_transport_bw(int id, tlm::tlm_generic_payload &payload,
tlm::tlm_phase &phase, sc_core::sc_time &bwDelay);
tlm::tlm_sync_enum nb_transport_fw(int id,
tlm::tlm_generic_payload& trans,
tlm::tlm_phase& phase,
sc_core::sc_time& fwDelay);
tlm::tlm_sync_enum nb_transport_bw(int id,
tlm::tlm_generic_payload& payload,
tlm::tlm_phase& phase,
sc_core::sc_time& bwDelay);
void b_transport(int id, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay);
unsigned int transport_dbg(int id, tlm::tlm_generic_payload& trans);
@@ -103,7 +108,8 @@ protected:
class ArbiterSimple final : public Arbiter
{
public:
ArbiterSimple(const sc_core::sc_module_name& name, const Configuration& config,
ArbiterSimple(const sc_core::sc_module_name& name,
const Configuration& config,
const AddressDecoder& addressDecoder);
SC_HAS_PROCESS(ArbiterSimple);
@@ -117,7 +123,8 @@ private:
class ArbiterFifo final : public Arbiter
{
public:
ArbiterFifo(const sc_core::sc_module_name& name, const Configuration& config,
ArbiterFifo(const sc_core::sc_module_name& name,
const Configuration& config,
const AddressDecoder& addressDecoder);
SC_HAS_PROCESS(ArbiterFifo);
@@ -138,7 +145,8 @@ private:
class ArbiterReorder final : public Arbiter
{
public:
ArbiterReorder(const sc_core::sc_module_name& name, const Configuration& config,
ArbiterReorder(const sc_core::sc_module_name& name,
const Configuration& config,
const AddressDecoder& addressDecoder);
SC_HAS_PROCESS(ArbiterReorder);
@@ -151,14 +159,17 @@ private:
struct ThreadPayloadIDCompare
{
bool operator() (const tlm::tlm_generic_payload* lhs, const tlm::tlm_generic_payload* rhs) const
bool operator()(const tlm::tlm_generic_payload* lhs,
const tlm::tlm_generic_payload* rhs) const
{
return ArbiterExtension::getThreadPayloadID(*lhs) < ArbiterExtension::getThreadPayloadID(*rhs);
return ArbiterExtension::getThreadPayloadID(*lhs) <
ArbiterExtension::getThreadPayloadID(*rhs);
}
};
ControllerVector<Thread, tlm::tlm_generic_payload*> outstandingEndReqOnThread;
ControllerVector<Thread, std::set<tlm::tlm_generic_payload*, ThreadPayloadIDCompare>> pendingResponsesOnThread;
ControllerVector<Thread, std::set<tlm::tlm_generic_payload*, ThreadPayloadIDCompare>>
pendingResponsesOnThread;
ControllerVector<Channel, sc_core::sc_time> lastEndReqOnChannel;
ControllerVector<Thread, sc_core::sc_time> lastEndRespOnThread;

View File

@@ -45,14 +45,14 @@
#include "DRAMSys/controller/Controller.h"
#include "DRAMSys/simulation/dram/DramDDR3.h"
#include "DRAMSys/simulation/dram/DramDDR4.h"
#include "DRAMSys/simulation/dram/DramWideIO.h"
#include "DRAMSys/simulation/dram/DramLPDDR4.h"
#include "DRAMSys/simulation/dram/DramWideIO2.h"
#include "DRAMSys/simulation/dram/DramHBM2.h"
#include "DRAMSys/simulation/dram/DramGDDR5.h"
#include "DRAMSys/simulation/dram/DramGDDR5X.h"
#include "DRAMSys/simulation/dram/DramGDDR6.h"
#include "DRAMSys/simulation/dram/DramHBM2.h"
#include "DRAMSys/simulation/dram/DramLPDDR4.h"
#include "DRAMSys/simulation/dram/DramSTTMRAM.h"
#include "DRAMSys/simulation/dram/DramWideIO.h"
#include "DRAMSys/simulation/dram/DramWideIO2.h"
#ifdef DDR5_SIM
#include "DRAMSys/simulation/dram/DramDDR5.h"
@@ -67,21 +67,23 @@
#include <cstdlib>
#include <iostream>
#include <memory>
#include <vector>
#include <stdexcept>
#include <vector>
namespace DRAMSys
{
DRAMSys::DRAMSys(const sc_core::sc_module_name& name,
const ::DRAMSys::Config::Configuration& configLib)
: DRAMSys(name, configLib, true)
{}
const ::DRAMSys::Config::Configuration& configLib) :
DRAMSys(name, configLib, true)
{
}
DRAMSys::DRAMSys(const sc_core::sc_module_name& name,
const ::DRAMSys::Config::Configuration& configLib,
bool initAndBind)
: sc_module(name), tSocket("DRAMSys_tSocket")
bool initAndBind) :
sc_module(name),
tSocket("DRAMSys_tSocket")
{
logo();
@@ -120,21 +122,17 @@ void DRAMSys::end_of_simulation()
void DRAMSys::logo()
{
#define GREENTXT(s) std::string(("\u001b[38;5;28m"+std::string((s))+"\033[0m"))
#define DGREENTXT(s) std::string(("\u001b[38;5;22m"+std::string((s))+"\033[0m"))
#define LGREENTXT(s) std::string(("\u001b[38;5;82m"+std::string((s))+"\033[0m"))
#define BLACKTXT(s) std::string(("\u001b[38;5;232m"+std::string((s))+"\033[0m"))
#define BOLDTXT(s) std::string(("\033[1;37m"+std::string((s))+"\033[0m"))
#define GREENTXT(s) std::string(("\u001b[38;5;28m" + std::string((s)) + "\033[0m"))
#define DGREENTXT(s) std::string(("\u001b[38;5;22m" + std::string((s)) + "\033[0m"))
#define LGREENTXT(s) std::string(("\u001b[38;5;82m" + std::string((s)) + "\033[0m"))
#define BLACKTXT(s) std::string(("\u001b[38;5;232m" + std::string((s)) + "\033[0m"))
#define BOLDTXT(s) std::string(("\033[1;37m" + std::string((s)) + "\033[0m"))
cout << std::endl
<< BLACKTXT("■ ■ ")<< DGREENTXT("")
<< BOLDTXT("DRAMSys5.0, Copyright (c) 2023")
<< BLACKTXT("■ ■ ") << DGREENTXT("") << BOLDTXT("DRAMSys5.0, Copyright (c) 2023")
<< std::endl
<< BLACKTXT("") << DGREENTXT("") << GREENTXT("")
<< "RPTU Kaiserslautern-Landau,"
<< std::endl
<< DGREENTXT("") << GREENTXT("") << LGREENTXT("" )
<< "Fraunhofer IESE"
<< BLACKTXT("") << DGREENTXT("") << GREENTXT("") << "RPTU Kaiserslautern-Landau,"
<< std::endl
<< DGREENTXT("") << GREENTXT("") << LGREENTXT("") << "Fraunhofer IESE" << std::endl
<< std::endl;
#undef GREENTXT
#undef DGREENTXT
@@ -173,45 +171,59 @@ void DRAMSys::instantiateModules(const ::DRAMSys::Config::AddressMapping& addres
MemSpec::MemoryType memoryType = config.memSpec->memoryType;
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
{
controllers.emplace_back(std::make_unique<Controller>(("controller" + std::to_string(i)).c_str(), config,
*addressDecoder));
controllers.emplace_back(std::make_unique<Controller>(
("controller" + std::to_string(i)).c_str(), config, *addressDecoder));
if (memoryType == MemSpec::MemoryType::DDR3)
drams.emplace_back(std::make_unique<DramDDR3>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramDDR3>(("dram" + std::to_string(i)).c_str(), config));
else if (memoryType == MemSpec::MemoryType::DDR4)
drams.emplace_back(std::make_unique<DramDDR4>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramDDR4>(("dram" + std::to_string(i)).c_str(), config));
else if (memoryType == MemSpec::MemoryType::WideIO)
drams.emplace_back(std::make_unique<DramWideIO>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramWideIO>(("dram" + std::to_string(i)).c_str(), config));
else if (memoryType == MemSpec::MemoryType::LPDDR4)
drams.emplace_back(std::make_unique<DramLPDDR4>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramLPDDR4>(("dram" + std::to_string(i)).c_str(), config));
else if (memoryType == MemSpec::MemoryType::WideIO2)
drams.emplace_back(std::make_unique<DramWideIO2>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramWideIO2>(("dram" + std::to_string(i)).c_str(), config));
else if (memoryType == MemSpec::MemoryType::HBM2)
drams.emplace_back(std::make_unique<DramHBM2>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramHBM2>(("dram" + std::to_string(i)).c_str(), config));
else if (memoryType == MemSpec::MemoryType::GDDR5)
drams.emplace_back(std::make_unique<DramGDDR5>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramGDDR5>(("dram" + std::to_string(i)).c_str(), config));
else if (memoryType == MemSpec::MemoryType::GDDR5X)
drams.emplace_back(std::make_unique<DramGDDR5X>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramGDDR5X>(("dram" + std::to_string(i)).c_str(), config));
else if (memoryType == MemSpec::MemoryType::GDDR6)
drams.emplace_back(std::make_unique<DramGDDR6>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramGDDR6>(("dram" + std::to_string(i)).c_str(), config));
else if (memoryType == MemSpec::MemoryType::STTMRAM)
drams.emplace_back(std::make_unique<DramSTTMRAM>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramSTTMRAM>(("dram" + std::to_string(i)).c_str(), config));
#ifdef DDR5_SIM
else if (memoryType == MemSpec::MemoryType::DDR5)
drams.emplace_back(std::make_unique<DramDDR5>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramDDR5>(("dram" + std::to_string(i)).c_str(), config));
#endif
#ifdef LPDDR5_SIM
else if (memoryType == MemSpec::MemoryType::LPDDR5)
drams.emplace_back(std::make_unique<DramLPDDR5>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramLPDDR5>(("dram" + std::to_string(i)).c_str(), config));
#endif
#ifdef HBM3_SIM
else if (memoryType == MemSpec::MemoryType::HBM3)
drams.emplace_back(std::make_unique<DramHBM3>(("dram" + std::to_string(i)).c_str(), config));
drams.emplace_back(
std::make_unique<DramHBM3>(("dram" + std::to_string(i)).c_str(), config));
#endif
if (config.checkTLM2Protocol)
controllersTlmCheckers.push_back(std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>
(("TlmCheckerController" + std::to_string(i)).c_str()));
controllersTlmCheckers.push_back(
std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>(
("TlmCheckerController" + std::to_string(i)).c_str()));
}
}

View File

@@ -41,18 +41,18 @@
#ifndef DRAMSYS_H
#define DRAMSYS_H
#include "DRAMSys/simulation/dram/Dram.h"
#include "DRAMSys/simulation/Arbiter.h"
#include "DRAMSys/simulation/ReorderBuffer.h"
#include "DRAMSys/common/tlm2_base_protocol_checker.h"
#include "DRAMSys/controller/ControllerIF.h"
#include "DRAMSys/simulation/AddressDecoder.h"
#include "DRAMSys/simulation/Arbiter.h"
#include "DRAMSys/simulation/ReorderBuffer.h"
#include "DRAMSys/simulation/dram/Dram.h"
#include "DRAMSys/config/DRAMSysConfiguration.h"
#include <string>
#include <list>
#include <memory>
#include <string>
#include <systemc>
#include <tlm>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
@@ -67,11 +67,10 @@ public:
tlm_utils::multi_passthrough_target_socket<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 ::DRAMSys::Config::Configuration& configLib);
const Configuration& getConfig() const;
const AddressDecoder &getAddressDecoder() const { return *addressDecoder; }
const AddressDecoder& getAddressDecoder() const { return *addressDecoder; }
protected:
DRAMSys(const sc_core::sc_module_name& name,
@@ -82,7 +81,7 @@ protected:
Configuration config;
//TLM 2.0 Protocol Checkers
// TLM 2.0 Protocol Checkers
std::vector<std::unique_ptr<tlm_utils::tlm2_base_protocol_checker<>>> controllersTlmCheckers;
// TODO: Each DRAM has a reorder buffer (check this!)

View File

@@ -36,19 +36,19 @@
#include "DRAMSysRecordable.h"
#include "DRAMSys/controller/ControllerRecordable.h"
#include "DRAMSys/common/TlmRecorder.h"
#include "DRAMSys/simulation/dram/DramRecordable.h"
#include "DRAMSys/controller/ControllerRecordable.h"
#include "DRAMSys/simulation/dram/DramDDR3.h"
#include "DRAMSys/simulation/dram/DramDDR4.h"
#include "DRAMSys/simulation/dram/DramWideIO.h"
#include "DRAMSys/simulation/dram/DramLPDDR4.h"
#include "DRAMSys/simulation/dram/DramWideIO2.h"
#include "DRAMSys/simulation/dram/DramHBM2.h"
#include "DRAMSys/simulation/dram/DramGDDR5.h"
#include "DRAMSys/simulation/dram/DramGDDR5X.h"
#include "DRAMSys/simulation/dram/DramGDDR6.h"
#include "DRAMSys/simulation/dram/DramHBM2.h"
#include "DRAMSys/simulation/dram/DramLPDDR4.h"
#include "DRAMSys/simulation/dram/DramRecordable.h"
#include "DRAMSys/simulation/dram/DramSTTMRAM.h"
#include "DRAMSys/simulation/dram/DramWideIO.h"
#include "DRAMSys/simulation/dram/DramWideIO2.h"
#ifdef DDR5_SIM
#include "DRAMSys/simulation/dram/DramDDR5.h"
@@ -65,8 +65,9 @@
namespace DRAMSys
{
DRAMSysRecordable::DRAMSysRecordable(const sc_core::sc_module_name& name, const ::DRAMSys::Config::Configuration& configLib)
: DRAMSys(name, configLib, false)
DRAMSysRecordable::DRAMSysRecordable(const sc_core::sc_module_name& name,
const ::DRAMSys::Config::Configuration& configLib) :
DRAMSys(name, configLib, false)
{
// If a simulation file is passed as argument to DRAMSys the simulation ID
// is prepended to the simulation name if found.
@@ -90,11 +91,11 @@ void DRAMSysRecordable::end_of_simulation()
// Report power before TLM recorders are finalized
if (config.powerAnalysis)
{
for (auto& dram: drams)
for (auto& dram : drams)
dram->reportPower();
}
for (auto& tlmRecorder: tlmRecorders)
for (auto& tlmRecorder : tlmRecorders)
tlmRecorder.finalize();
}
@@ -108,7 +109,8 @@ void DRAMSysRecordable::setupTlmRecorders(const std::string& traceName,
tlmRecorders.reserve(config.memSpec->numberOfChannels);
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
{
std::string dbName = std::string(name()) + "_" + traceName + "_ch" + std::to_string(i) + ".tdb";
std::string dbName =
std::string(name()) + "_" + traceName + "_ch" + std::to_string(i) + ".tdb";
std::string recorderName = "tlmRecorder" + std::to_string(i);
nlohmann::json mcconfig;
@@ -145,58 +147,59 @@ void DRAMSysRecordable::instantiateModules(const std::string& traceName,
MemSpec::MemoryType memoryType = config.memSpec->memoryType;
for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++)
{
controllers.emplace_back(std::make_unique<ControllerRecordable>(("controller" + std::to_string(i)).c_str(),
config, *addressDecoder, tlmRecorders[i]));
controllers.emplace_back(std::make_unique<ControllerRecordable>(
("controller" + std::to_string(i)).c_str(), config, *addressDecoder, tlmRecorders[i]));
if (memoryType == MemSpec::MemoryType::DDR3)
drams.emplace_back(std::make_unique<DramRecordable<DramDDR3>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramDDR3>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
else if (memoryType == MemSpec::MemoryType::DDR4)
drams.emplace_back(std::make_unique<DramRecordable<DramDDR4>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramDDR4>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
else if (memoryType == MemSpec::MemoryType::WideIO)
drams.emplace_back(std::make_unique<DramRecordable<DramWideIO>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramWideIO>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
else if (memoryType == MemSpec::MemoryType::LPDDR4)
drams.emplace_back(std::make_unique<DramRecordable<DramLPDDR4>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramLPDDR4>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
else if (memoryType == MemSpec::MemoryType::WideIO2)
drams.emplace_back(std::make_unique<DramRecordable<DramWideIO2>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramWideIO2>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
else if (memoryType == MemSpec::MemoryType::HBM2)
drams.emplace_back(std::make_unique<DramRecordable<DramHBM2>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramHBM2>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
else if (memoryType == MemSpec::MemoryType::GDDR5)
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR5>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR5>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
else if (memoryType == MemSpec::MemoryType::GDDR5X)
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR5X>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR5X>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
else if (memoryType == MemSpec::MemoryType::GDDR6)
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR6>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramGDDR6>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
else if (memoryType == MemSpec::MemoryType::STTMRAM)
drams.emplace_back(std::make_unique<DramRecordable<DramSTTMRAM>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramSTTMRAM>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
#ifdef DDR5_SIM
else if (memoryType == MemSpec::MemoryType::DDR5)
drams.emplace_back(std::make_unique<DramRecordable<DramDDR5>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramDDR5>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
#endif
#ifdef LPDDR5_SIM
else if (memoryType == MemSpec::MemoryType::LPDDR5)
drams.emplace_back(std::make_unique<DramRecordable<DramLPDDR5>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramLPDDR5>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
#endif
#ifdef HBM3_SIM
else if (memoryType == MemSpec::MemoryType::HBM3)
drams.emplace_back(std::make_unique<DramRecordable<DramHBM3>>(("dram" + std::to_string(i)).c_str(),
config, tlmRecorders[i]));
drams.emplace_back(std::make_unique<DramRecordable<DramHBM3>>(
("dram" + std::to_string(i)).c_str(), config, tlmRecorders[i]));
#endif
if (config.checkTLM2Protocol)
controllersTlmCheckers.emplace_back(std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>
(("TLMCheckerController" + std::to_string(i)).c_str()));
controllersTlmCheckers.emplace_back(
std::make_unique<tlm_utils::tlm2_base_protocol_checker<>>(
("TLMCheckerController" + std::to_string(i)).c_str()));
}
}

Some files were not shown because too many files have changed in this diff Show More