From 0479184f7276a7fd28e7725bc9203de75197aa18 Mon Sep 17 00:00:00 2001 From: Jonathan Hager Date: Tue, 11 Mar 2025 12:57:02 +0100 Subject: [PATCH] Split the bandwidth recording in two modules This allows separate recording of the bandwidth between Arbiter - Controller and Controller - Dram --- src/libdramsys/CMakeLists.txt | 3 +- .../DRAMSys/common/TlmRecorderArbiter.cpp | 99 +++++++++++++++++++ .../DRAMSys/common/TlmRecorderArbiter.h | 61 ++++++++++++ ...ecorderWrapper.cpp => TlmRecorderDram.cpp} | 39 ++++---- ...TlmRecorderWrapper.h => TlmRecorderDram.h} | 23 +++-- .../DRAMSys/controller/Controller.cpp | 3 - src/libdramsys/DRAMSys/simulation/DRAMSys.cpp | 57 +++++++---- src/libdramsys/DRAMSys/simulation/DRAMSys.h | 7 +- 8 files changed, 241 insertions(+), 51 deletions(-) create mode 100644 src/libdramsys/DRAMSys/common/TlmRecorderArbiter.cpp create mode 100644 src/libdramsys/DRAMSys/common/TlmRecorderArbiter.h rename src/libdramsys/DRAMSys/common/{TlmRecorderWrapper.cpp => TlmRecorderDram.cpp} (69%) rename src/libdramsys/DRAMSys/common/{TlmRecorderWrapper.h => TlmRecorderDram.h} (71%) diff --git a/src/libdramsys/CMakeLists.txt b/src/libdramsys/CMakeLists.txt index 8c039694..6b41fee7 100644 --- a/src/libdramsys/CMakeLists.txt +++ b/src/libdramsys/CMakeLists.txt @@ -39,7 +39,8 @@ add_library(libdramsys DRAMSys/common/DebugManager.cpp DRAMSys/common/TlmRecorder.cpp - DRAMSys/common/TlmRecorderWrapper.cpp + DRAMSys/common/TlmRecorderArbiter.cpp + DRAMSys/common/TlmRecorderDram.cpp DRAMSys/common/dramExtensions.cpp DRAMSys/common/utils.cpp DRAMSys/configuration/memspec/MemSpec.cpp diff --git a/src/libdramsys/DRAMSys/common/TlmRecorderArbiter.cpp b/src/libdramsys/DRAMSys/common/TlmRecorderArbiter.cpp new file mode 100644 index 00000000..66d3facc --- /dev/null +++ b/src/libdramsys/DRAMSys/common/TlmRecorderArbiter.cpp @@ -0,0 +1,99 @@ +#include "TlmRecorderArbiter.h" + +#include "DRAMSys/configuration/memspec/MemSpec.h" +#include "DRAMSys/controller/Command.h" +#include "DRAMSys/simulation/SimConfig.h" +#include +#include +#include + +namespace DRAMSys +{ + +TlmRecorderArbiter::TlmRecorderArbiter(const sc_core::sc_module_name& name, + const SimConfig& simConfig, + const MemSpec& memSpec, + TlmRecorder& tlmRecorder, + bool enableBandwidth) : + sc_module(name), + memSpec(memSpec), + tlmRecorder(tlmRecorder), + enableWindowing(simConfig.enableWindowing), + pseudoChannelMode(memSpec.pseudoChannelMode()), + ranksPerChannel(memSpec.ranksPerChannel), + windowSizeTime(simConfig.windowSize * memSpec.tCK), + numberOfBytesServed(0), + activeTimeMultiplier(memSpec.tCK / memSpec.dataRate), + enableBandwidth(enableBandwidth) +{ + iSocket.register_nb_transport_bw(this, &TlmRecorderArbiter::nb_transport_bw); + tSocket.register_nb_transport_fw(this, &TlmRecorderArbiter::nb_transport_fw); + + if (enableBandwidth) + { + SC_METHOD(recordBandwidth); + sensitive << windowEvent; + + if (enableWindowing) + { + windowEvent.notify(windowSizeTime); + nextWindowEventTime = windowSizeTime; + } + } +} + +tlm::tlm_sync_enum TlmRecorderArbiter::nb_transport_fw(tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& delay) +{ + if (enableBandwidth && enableWindowing) + { + if (phase == tlm::BEGIN_REQ && trans.is_write()) + numberOfBytesServed += trans.get_data_length(); + } + + tlmRecorder.recordPhase(trans, phase, delay); + return iSocket->nb_transport_fw(trans, phase, delay); +} + +tlm::tlm_sync_enum TlmRecorderArbiter::nb_transport_bw(tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& delay) +{ + if (enableBandwidth && enableWindowing) + { + if (phase == tlm::BEGIN_RESP && trans.is_read()) + numberOfBytesServed += trans.get_data_length(); + } + + tlmRecorder.recordPhase(trans, phase, delay); + return tSocket->nb_transport_bw(trans, phase, delay); +} + +void TlmRecorderArbiter::recordBandwidth() +{ + if (enableBandwidth && enableWindowing && sc_core::sc_time_stamp() == nextWindowEventTime) + { + windowEvent.notify(windowSizeTime); + nextWindowEventTime += windowSizeTime; + + uint64_t windowNumberOfBytesServed = numberOfBytesServed - lastNumberOfBytesServed; + lastNumberOfBytesServed = numberOfBytesServed; + + // HBM specific, pseudo channels get averaged + if (pseudoChannelMode) + windowNumberOfBytesServed /= ranksPerChannel; + + double windowBandwidth = + static_cast(windowNumberOfBytesServed) / (windowSizeTime.to_seconds()); + tlmRecorder.recordBandwidth(sc_core::sc_time_stamp().to_seconds(), windowBandwidth); + + // sc_core::sc_time windowActiveTime = + // activeTimeMultiplier * static_cast(windowNumberOfBytesServed); + // double windowAverageBandwidth = windowNumberOfBytesServed / maxBandwidth; + // tlmRecorder.recordBandwidth(sc_core::sc_time_stamp().to_seconds(), + // windowAverageBandwidth); + } +} + +} // namespace DRAMSys diff --git a/src/libdramsys/DRAMSys/common/TlmRecorderArbiter.h b/src/libdramsys/DRAMSys/common/TlmRecorderArbiter.h new file mode 100644 index 00000000..ef3f5416 --- /dev/null +++ b/src/libdramsys/DRAMSys/common/TlmRecorderArbiter.h @@ -0,0 +1,61 @@ +#ifndef TLMRECORDERARBITER_H +#define TLMRECORDERARBITER_H + +#include "DRAMSys/configuration/memspec/MemSpec.h" +#include "DRAMSys/simulation/SimConfig.h" +#include "TlmRecorder.h" + +#include +#include +#include +#include +#include + +namespace DRAMSys +{ + +class TlmRecorderArbiter : public sc_core::sc_module + +{ + SC_HAS_PROCESS(TlmRecorderArbiter); + +public: + tlm_utils::simple_initiator_socket iSocket; + tlm_utils::simple_target_socket tSocket; + + TlmRecorderArbiter(const sc_core::sc_module_name& name, + const SimConfig& simConfig, + const MemSpec& memspec, + TlmRecorder& tlmRecorder, + bool enableBandwidth); + ~TlmRecorderArbiter() = default; + + tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& delay); + tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& delay); + +private: + const MemSpec& memSpec; + // HACK: Refactor with shared pointers? + TlmRecorder& tlmRecorder; + const bool enableWindowing; + const bool pseudoChannelMode; + const unsigned int ranksPerChannel; + const sc_core::sc_time windowSizeTime; + sc_core::sc_event windowEvent; + sc_core::sc_time nextWindowEventTime; + uint64_t numberOfBytesServed; + uint64_t lastNumberOfBytesServed = 0; + const sc_core::sc_time activeTimeMultiplier; + + bool enableBandwidth = false; + + void recordBandwidth(); +}; + +} // namespace DRAMSys + +#endif // TLMRECORDERARBITER_H diff --git a/src/libdramsys/DRAMSys/common/TlmRecorderWrapper.cpp b/src/libdramsys/DRAMSys/common/TlmRecorderDram.cpp similarity index 69% rename from src/libdramsys/DRAMSys/common/TlmRecorderWrapper.cpp rename to src/libdramsys/DRAMSys/common/TlmRecorderDram.cpp index 8cf53a5a..48856db7 100644 --- a/src/libdramsys/DRAMSys/common/TlmRecorderWrapper.cpp +++ b/src/libdramsys/DRAMSys/common/TlmRecorderDram.cpp @@ -1,4 +1,4 @@ -#include "TlmRecorderWrapper.h" +#include "TlmRecorderDram.h" #include "DRAMSys/configuration/memspec/MemSpec.h" #include "DRAMSys/controller/Command.h" #include "DRAMSys/simulation/SimConfig.h" @@ -9,10 +9,11 @@ namespace DRAMSys { -TlmRecorderWrapper::TlmRecorderWrapper(const sc_core::sc_module_name& name, +TlmRecorderDram::TlmRecorderDram(const sc_core::sc_module_name& name, const SimConfig& simConfig, const MemSpec& memSpec, - TlmRecorder& tlmRecorder) : + TlmRecorder& tlmRecorder, + bool enableBandwidth) : sc_module(name), tlmRecorder(tlmRecorder), enableWindowing(simConfig.enableWindowing), @@ -20,26 +21,30 @@ TlmRecorderWrapper::TlmRecorderWrapper(const sc_core::sc_module_name& name, ranksPerChannel(memSpec.ranksPerChannel), windowSizeTime(simConfig.windowSize * memSpec.tCK), numberOfBeatsServed(memSpec.ranksPerChannel, 0), - activeTimeMultiplier(memSpec.tCK / memSpec.dataRate) + activeTimeMultiplier(memSpec.tCK / memSpec.dataRate), + enableBandwidth(enableBandwidth) { - iSocket.register_nb_transport_bw(this, &TlmRecorderWrapper::nb_transport_bw); - tSocket.register_nb_transport_fw(this, &TlmRecorderWrapper::nb_transport_fw); + iSocket.register_nb_transport_bw(this, &TlmRecorderDram::nb_transport_bw); + tSocket.register_nb_transport_fw(this, &TlmRecorderDram::nb_transport_fw); - SC_METHOD(recordBandwidth); - sensitive << windowEvent; - - if (enableWindowing) + if (enableBandwidth) { - windowEvent.notify(windowSizeTime); - nextWindowEventTime = windowSizeTime; + SC_METHOD(recordBandwidth); + sensitive << windowEvent; + + if (enableWindowing) + { + windowEvent.notify(windowSizeTime); + nextWindowEventTime = windowSizeTime; + } } } -tlm::tlm_sync_enum TlmRecorderWrapper::nb_transport_fw(tlm::tlm_generic_payload& trans, +tlm::tlm_sync_enum TlmRecorderDram::nb_transport_fw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay) { - if (enableWindowing) + if (enableBandwidth && enableWindowing) { Command cmd{phase}; if (cmd.isCasCommand()) @@ -54,7 +59,7 @@ tlm::tlm_sync_enum TlmRecorderWrapper::nb_transport_fw(tlm::tlm_generic_payload& return iSocket->nb_transport_fw(trans, phase, delay); } -tlm::tlm_sync_enum TlmRecorderWrapper::nb_transport_bw(tlm::tlm_generic_payload& trans, +tlm::tlm_sync_enum TlmRecorderDram::nb_transport_bw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay) { @@ -62,9 +67,9 @@ tlm::tlm_sync_enum TlmRecorderWrapper::nb_transport_bw(tlm::tlm_generic_payload& return tSocket->nb_transport_bw(trans, phase, delay); } -void TlmRecorderWrapper::recordBandwidth() +void TlmRecorderDram::recordBandwidth() { - if (enableWindowing && sc_core::sc_time_stamp() == nextWindowEventTime) + if (enableBandwidth && enableWindowing && sc_core::sc_time_stamp() == nextWindowEventTime) { windowEvent.notify(windowSizeTime); nextWindowEventTime += windowSizeTime; diff --git a/src/libdramsys/DRAMSys/common/TlmRecorderWrapper.h b/src/libdramsys/DRAMSys/common/TlmRecorderDram.h similarity index 71% rename from src/libdramsys/DRAMSys/common/TlmRecorderWrapper.h rename to src/libdramsys/DRAMSys/common/TlmRecorderDram.h index 2523763b..fd5d2aa7 100644 --- a/src/libdramsys/DRAMSys/common/TlmRecorderWrapper.h +++ b/src/libdramsys/DRAMSys/common/TlmRecorderDram.h @@ -1,5 +1,5 @@ -#ifndef TLMRECORDERWRAPPER_H -#define TLMRECORDERWRAPPER_H +#ifndef TLMRECORDERDRAM_H +#define TLMRECORDERDRAM_H #include "DRAMSys/configuration/memspec/MemSpec.h" #include "DRAMSys/simulation/SimConfig.h" @@ -14,20 +14,21 @@ namespace DRAMSys { -class TlmRecorderWrapper : public sc_core::sc_module +class TlmRecorderDram : public sc_core::sc_module { - SC_HAS_PROCESS(TlmRecorderWrapper); + SC_HAS_PROCESS(TlmRecorderDram); public: - tlm_utils::simple_initiator_socket iSocket; - tlm_utils::simple_target_socket tSocket; + tlm_utils::simple_initiator_socket iSocket; + tlm_utils::simple_target_socket tSocket; - TlmRecorderWrapper(const sc_core::sc_module_name& name, + TlmRecorderDram(const sc_core::sc_module_name& name, const SimConfig& simConfig, const MemSpec& memspec, - TlmRecorder& tlmRecorder); - ~TlmRecorderWrapper() = default; + TlmRecorder& tlmRecorder, + bool enableBandwidth); + ~TlmRecorderDram() = default; tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, @@ -49,9 +50,11 @@ private: uint64_t lastNumberOfBeatsServed = 0; const sc_core::sc_time activeTimeMultiplier; + bool enableBandwidth = false; + void recordBandwidth(); }; } // namespace DRAMSys -#endif // TLMRECORDERWRAPPER_H +#endif // TLMRECORDERDRAM_H diff --git a/src/libdramsys/DRAMSys/controller/Controller.cpp b/src/libdramsys/DRAMSys/controller/Controller.cpp index 802489c1..50f86ca8 100644 --- a/src/libdramsys/DRAMSys/controller/Controller.cpp +++ b/src/libdramsys/DRAMSys/controller/Controller.cpp @@ -342,10 +342,8 @@ void Controller::registerIdleCallback(std::function idleCallback) void Controller::recordBufferDepth() { - std::cout << "Method called "; if (sc_time_stamp() == nextWindowEventTime) { - std::cout << "If entered\n"; windowEvent.notify(windowSizeTime); nextWindowEventTime += windowSizeTime; @@ -355,7 +353,6 @@ void Controller::recordBufferDepth() slidingAverageBufferDepth[index] = SC_ZERO_TIME; } - std::cout << windowAverageBufferDepth[0] << "\n"; tlmRecorder.recordBufferDepth(sc_time_stamp().to_seconds(), windowAverageBufferDepth); } } diff --git a/src/libdramsys/DRAMSys/simulation/DRAMSys.cpp b/src/libdramsys/DRAMSys/simulation/DRAMSys.cpp index 6d3da436..e86da6ef 100644 --- a/src/libdramsys/DRAMSys/simulation/DRAMSys.cpp +++ b/src/libdramsys/DRAMSys/simulation/DRAMSys.cpp @@ -106,16 +106,13 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name& name, const Config::Configuratio // Create controllers and DRAMs for (std::size_t i = 0; i < memSpec->numberOfChannels; i++) { - // controllers.emplace_back( - // std::make_unique(("controller" + std::to_string(i)).c_str(), - // mcConfig, - // simConfig, - // *memSpec, - // *addressDecoder, - // tlmRecorders[i])); - - controllers.emplace_back(std::make_unique( - ("controller" + std::to_string(i)).c_str(), mcConfig, *memSpec, simConfig, *addressDecoder, tlmRecorders[i])); + controllers.emplace_back( + std::make_unique(("controller" + std::to_string(i)).c_str(), + mcConfig, + *memSpec, + simConfig, + *addressDecoder, + tlmRecorders[i])); drams.emplace_back(std::make_unique( ("dram" + std::to_string(i)).c_str(), simConfig, *memSpec, tlmRecorders[i])); @@ -125,19 +122,34 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name& name, const Config::Configuratio std::make_unique>( ("TLMCheckerController" + std::to_string(i)).c_str())); - tlmWrappers.emplace_back(std::make_unique( + // Not recording bandwidth between Arbiter - Controller + tlmWrappersArbiter.emplace_back(std::make_unique( ("TlmRecorderWrapper" + std::to_string(i)).c_str(), simConfig, *memSpec, - tlmRecorders[i])); + tlmRecorders[i], + false)); + + // Recording bandwidth between Controller - DRAM + tlmWrappersDram.emplace_back(std::make_unique( + ("TlmRecorderWrapper" + std::to_string(i)).c_str(), + simConfig, + *memSpec, + tlmRecorders[i], + true)); } } else { for (std::size_t i = 0; i < memSpec->numberOfChannels; i++) { - controllers.emplace_back(std::make_unique( - ("controller" + std::to_string(i)).c_str(), mcConfig, *memSpec, simConfig, *addressDecoder, tlmRecorders[i])); + controllers.emplace_back( + std::make_unique(("controller" + std::to_string(i)).c_str(), + mcConfig, + *memSpec, + simConfig, + *addressDecoder, + tlmRecorders[i])); drams.emplace_back(std::make_unique( ("dram" + std::to_string(i)).c_str(), simConfig, *memSpec, tlmRecorders[i])); @@ -155,11 +167,22 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name& name, const Config::Configuratio tSocket.bind(arbiter->tSocket); for (unsigned i = 0; i < memSpec->numberOfChannels; i++) { - if (simConfig.checkTLM2Protocol) + if (simConfig.checkTLM2Protocol && simConfig.databaseRecording) + { + arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); + controllersTlmCheckers[i]->initiator_socket.bind(tlmWrappersArbiter[i]->tSocket); + tlmWrappersArbiter[i]->iSocket.bind(controllers[i]->tSocket); + } + else if (simConfig.checkTLM2Protocol) { arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); controllersTlmCheckers[i]->initiator_socket.bind(controllers[i]->tSocket); } + else if (simConfig.databaseRecording) + { + arbiter->iSocket.bind(tlmWrappersArbiter[i]->tSocket); + tlmWrappersArbiter[i]->iSocket.bind(controllers[i]->tSocket); + } else { arbiter->iSocket.bind(controllers[i]->tSocket); @@ -168,8 +191,8 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name& name, const Config::Configuratio // TODO: comments if (simConfig.databaseRecording) { - controllers[i]->iSocket.bind(tlmWrappers[i]->tSocket); - tlmWrappers[i]->iSocket.bind(drams[i]->tSocket); + controllers[i]->iSocket.bind(tlmWrappersDram[i]->tSocket); + tlmWrappersDram[i]->iSocket.bind(drams[i]->tSocket); } else { diff --git a/src/libdramsys/DRAMSys/simulation/DRAMSys.h b/src/libdramsys/DRAMSys/simulation/DRAMSys.h index 66b9a9ee..e721391c 100644 --- a/src/libdramsys/DRAMSys/simulation/DRAMSys.h +++ b/src/libdramsys/DRAMSys/simulation/DRAMSys.h @@ -42,7 +42,8 @@ #define DRAMSYS_H #include "DRAMSys/common/TlmRecorder.h" -#include "DRAMSys/common/TlmRecorderWrapper.h" +#include "DRAMSys/common/TlmRecorderArbiter.h" +#include "DRAMSys/common/TlmRecorderDram.h" #include "DRAMSys/common/tlm2_base_protocol_checker.h" #include "DRAMSys/config/DRAMSysConfiguration.h" #include "DRAMSys/controller/Controller.h" @@ -128,8 +129,8 @@ private: // They generate the output databases. std::vector tlmRecorders; - // TODO: Comments - std::vector> tlmWrappers; + std::vector> tlmWrappersArbiter; + std::vector> tlmWrappersDram; }; } // namespace DRAMSys