Format all files
This commit is contained in:
@@ -78,6 +78,6 @@ NLOHMANN_JSONIFY_ALL_THINGS(AddressMapping,
|
||||
CHANNEL_BIT,
|
||||
XOR)
|
||||
|
||||
} // namespace Configuration
|
||||
} // namespace DRAMSys::Config
|
||||
|
||||
#endif // DRAMSYSCONFIGURATION_ADDRESSMAPPING_H
|
||||
|
||||
@@ -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, ¤t_sub_config, resourceDirectory](
|
||||
int depth, nlohmann::detail::parse_event_t event, json_t &parsed) -> bool {
|
||||
parser_callback = [&parser_callback, ¤t_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>();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -37,10 +37,10 @@
|
||||
|
||||
#include "DRAMSys/controller/respqueue/RespQueueIF.h"
|
||||
|
||||
#include <utility>
|
||||
#include <queue>
|
||||
#include <systemc>
|
||||
#include <tlm>
|
||||
#include <utility>
|
||||
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
|
||||
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
|
||||
|
||||
#include <vector>
|
||||
#include <tlm>
|
||||
#include <vector>
|
||||
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
|
||||
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
|
||||
|
||||
#include <vector>
|
||||
#include <tlm>
|
||||
#include <vector>
|
||||
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
|
||||
#include "DRAMSys/controller/scheduler/BufferCounterIF.h"
|
||||
|
||||
#include <vector>
|
||||
#include <tlm>
|
||||
#include <vector>
|
||||
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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!)
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user