From e409bab47a3b2151c4bd5ff4e3e39e70260d436c Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Mon, 18 Nov 2024 13:18:33 +0100 Subject: [PATCH] Implement pseudo-channel and rank specific BW information --- .../configuration/memspec/MemSpecDDR5.cpp | 1 - .../configuration/memspec/MemSpecHBM3.cpp | 6 +- .../configuration/memspec/MemSpecHBM3.h | 1 + .../configuration/memspec/MemSpecLPDDR5.cpp | 1 - src/libdramsys/DRAMSys/common/TlmRecorder.cpp | 14 +-- .../DRAMSys/configuration/memspec/MemSpec.cpp | 7 +- .../DRAMSys/configuration/memspec/MemSpec.h | 3 +- .../configuration/memspec/MemSpecDDR3.cpp | 1 - .../configuration/memspec/MemSpecDDR4.cpp | 1 - .../configuration/memspec/MemSpecGDDR5.cpp | 1 - .../configuration/memspec/MemSpecGDDR5X.cpp | 1 - .../configuration/memspec/MemSpecGDDR6.cpp | 1 - .../configuration/memspec/MemSpecHBM2.cpp | 6 +- .../configuration/memspec/MemSpecHBM2.h | 1 + .../configuration/memspec/MemSpecLPDDR4.cpp | 1 - .../configuration/memspec/MemSpecSTTMRAM.cpp | 1 - .../configuration/memspec/MemSpecWideIO.cpp | 1 - .../configuration/memspec/MemSpecWideIO2.cpp | 1 - .../DRAMSys/controller/Controller.cpp | 87 +++++++++++++++---- .../DRAMSys/controller/Controller.h | 2 +- .../controller/ControllerRecordable.cpp | 12 +-- 21 files changed, 98 insertions(+), 52 deletions(-) diff --git a/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.cpp b/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.cpp index 950c7cfc..81df906e 100644 --- a/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.cpp +++ b/extensions/standards/DDR5/DRAMSys/configuration/memspec/MemSpecDDR5.cpp @@ -49,7 +49,6 @@ namespace DRAMSys MemSpecDDR5::MemSpecDDR5(const Config::MemSpec& memSpec) : MemSpec(memSpec, memSpec.memarchitecturespec.entries.at("nbrOfChannels"), - 1, memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), diff --git a/extensions/standards/HBM3/DRAMSys/configuration/memspec/MemSpecHBM3.cpp b/extensions/standards/HBM3/DRAMSys/configuration/memspec/MemSpecHBM3.cpp index 255e43ba..3ec5431b 100644 --- a/extensions/standards/HBM3/DRAMSys/configuration/memspec/MemSpecHBM3.cpp +++ b/extensions/standards/HBM3/DRAMSys/configuration/memspec/MemSpecHBM3.cpp @@ -49,7 +49,6 @@ MemSpecHBM3::MemSpecHBM3(const Config::MemSpec& memSpec) : MemSpec(memSpec, 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") / @@ -140,6 +139,11 @@ bool MemSpecHBM3::hasRasAndCasBus() const return true; } +bool MemSpecHBM3::pseudoChannelMode() const +{ + return true; +} + sc_time MemSpecHBM3::getExecutionTime(Command command, const tlm_generic_payload& payload) const { if (command == Command::PREPB || command == Command::PREAB) diff --git a/extensions/standards/HBM3/DRAMSys/configuration/memspec/MemSpecHBM3.h b/extensions/standards/HBM3/DRAMSys/configuration/memspec/MemSpecHBM3.h index 1f0d31fc..41e3cb62 100644 --- a/extensions/standards/HBM3/DRAMSys/configuration/memspec/MemSpecHBM3.h +++ b/extensions/standards/HBM3/DRAMSys/configuration/memspec/MemSpecHBM3.h @@ -97,6 +97,7 @@ public: [[nodiscard]] unsigned getRAAMMT() const override; [[nodiscard]] bool hasRasAndCasBus() const override; + [[nodiscard]] bool pseudoChannelMode() const override; [[nodiscard]] sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override; diff --git a/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.cpp b/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.cpp index 4b2d37fb..2c7d9398 100644 --- a/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.cpp +++ b/extensions/standards/LPDDR5/DRAMSys/configuration/memspec/MemSpecLPDDR5.cpp @@ -48,7 +48,6 @@ namespace DRAMSys MemSpecLPDDR5::MemSpecLPDDR5(const Config::MemSpec& memSpec) : MemSpec(memSpec, memSpec.memarchitecturespec.entries.at("nbrOfChannels"), - 1, memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), diff --git a/src/libdramsys/DRAMSys/common/TlmRecorder.cpp b/src/libdramsys/DRAMSys/common/TlmRecorder.cpp index c690bec8..5dfce8ab 100644 --- a/src/libdramsys/DRAMSys/common/TlmRecorder.cpp +++ b/src/libdramsys/DRAMSys/common/TlmRecorder.cpp @@ -472,18 +472,8 @@ void TlmRecorder::insertGeneralInfo(const std::string& mcConfigString, sqlite3_bind_int(insertGeneralInfoStatement, 13, static_cast(mcConfig.requestBufferSize)); sqlite3_bind_int(insertGeneralInfoStatement, 14, static_cast(memSpec.getPer2BankOffset())); - const auto memoryType = memSpec.memoryType; - - bool rowColumnCommandBus = - (memoryType == Config::MemoryType::HBM2) || (memoryType == Config::MemoryType::HBM3); - - bool pseudoChannelMode = [this, memoryType]() -> bool - { - if (memoryType != Config::MemoryType::HBM2 && memoryType != Config::MemoryType::HBM3) - return false; - - return memSpec.pseudoChannelsPerChannel != 1; - }(); + bool rowColumnCommandBus = memSpec.hasRasAndCasBus(); + bool pseudoChannelMode = memSpec.pseudoChannelMode(); sqlite3_bind_int(insertGeneralInfoStatement, 15, static_cast(rowColumnCommandBus)); sqlite3_bind_int(insertGeneralInfoStatement, 16, static_cast(pseudoChannelMode)); diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpec.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpec.cpp index 11c5df79..812ab40b 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpec.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpec.cpp @@ -44,7 +44,6 @@ namespace DRAMSys MemSpec::MemSpec(const Config::MemSpec& memSpec, unsigned numberOfChannels, - unsigned pseudoChannelsPerChannel, unsigned ranksPerChannel, unsigned banksPerRank, unsigned groupsPerRank, @@ -53,7 +52,6 @@ MemSpec::MemSpec(const Config::MemSpec& memSpec, unsigned bankGroupsPerChannel, unsigned devicesPerRank) : numberOfChannels(numberOfChannels), - pseudoChannelsPerChannel(pseudoChannelsPerChannel), ranksPerChannel(ranksPerChannel), banksPerRank(banksPerRank), groupsPerRank(groupsPerRank), @@ -150,6 +148,11 @@ bool MemSpec::hasRasAndCasBus() const return false; } +bool MemSpec::pseudoChannelMode() const +{ + return false; +} + bool MemSpec::requiresMaskedWrite(const tlm::tlm_generic_payload& payload) const { if (allBytesEnabled(payload)) diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpec.h b/src/libdramsys/DRAMSys/configuration/memspec/MemSpec.h index e489ac3e..89357e68 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpec.h +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpec.h @@ -64,7 +64,6 @@ public: virtual ~MemSpec() = default; const unsigned numberOfChannels; - const unsigned pseudoChannelsPerChannel; const unsigned ranksPerChannel; const unsigned banksPerRank; const unsigned groupsPerRank; @@ -101,6 +100,7 @@ public: [[nodiscard]] virtual unsigned getRAADEC() const; [[nodiscard]] virtual bool hasRasAndCasBus() const; + [[nodiscard]] virtual bool pseudoChannelMode() const; [[nodiscard]] virtual sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const = 0; @@ -119,7 +119,6 @@ public: protected: MemSpec(const Config::MemSpec& memSpec, unsigned numberOfChannels, - unsigned pseudoChannelsPerChannel, unsigned ranksPerChannel, unsigned banksPerRank, unsigned groupsPerRank, diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR3.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR3.cpp index b1e5015a..d7664baa 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR3.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR3.cpp @@ -49,7 +49,6 @@ namespace DRAMSys MemSpecDDR3::MemSpecDDR3(const Config::MemSpec& memSpec) : MemSpec(memSpec, memSpec.memarchitecturespec.entries.at("nbrOfChannels"), - 1, memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"), 1, diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR4.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR4.cpp index 534398b3..65ebf380 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR4.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecDDR4.cpp @@ -49,7 +49,6 @@ namespace DRAMSys MemSpecDDR4::MemSpecDDR4(const Config::MemSpec& memSpec) : MemSpec(memSpec, memSpec.memarchitecturespec.entries.at("nbrOfChannels"), - 1, memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5.cpp index 769223a8..a0a095d1 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5.cpp @@ -49,7 +49,6 @@ namespace DRAMSys MemSpecGDDR5::MemSpecGDDR5(const Config::MemSpec& memSpec) : MemSpec(memSpec, memSpec.memarchitecturespec.entries.at("nbrOfChannels"), - 1, memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5X.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5X.cpp index 6a044877..92d4fd2f 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5X.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR5X.cpp @@ -49,7 +49,6 @@ namespace DRAMSys MemSpecGDDR5X::MemSpecGDDR5X(const Config::MemSpec& memSpec) : MemSpec(memSpec, memSpec.memarchitecturespec.entries.at("nbrOfChannels"), - 1, memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR6.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR6.cpp index efecb9c6..d560177d 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR6.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecGDDR6.cpp @@ -49,7 +49,6 @@ namespace DRAMSys MemSpecGDDR6::MemSpecGDDR6(const Config::MemSpec& memSpec) : MemSpec(memSpec, memSpec.memarchitecturespec.entries.at("nbrOfChannels"), - 1, memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"), memSpec.memarchitecturespec.entries.at("nbrOfBankGroups"), diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.cpp index 57de0491..0aeb6404 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.cpp @@ -50,7 +50,6 @@ MemSpecHBM2::MemSpecHBM2(const Config::MemSpec& memSpec) : MemSpec(memSpec, 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") / @@ -129,6 +128,11 @@ bool MemSpecHBM2::hasRasAndCasBus() const return true; } +bool MemSpecHBM2::pseudoChannelMode() const +{ + return ranksPerChannel != 1; +} + sc_time MemSpecHBM2::getExecutionTime(Command command, const tlm_generic_payload& payload) const { if (command == Command::PREPB || command == Command::PREAB) diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.h b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.h index fa2b2a33..b9a7e431 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.h +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecHBM2.h @@ -89,6 +89,7 @@ public: [[nodiscard]] sc_core::sc_time getRefreshIntervalPB() const override; [[nodiscard]] bool hasRasAndCasBus() const override; + [[nodiscard]] bool pseudoChannelMode() const override; [[nodiscard]] sc_core::sc_time getExecutionTime(Command command, const tlm::tlm_generic_payload& payload) const override; diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecLPDDR4.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecLPDDR4.cpp index dcc813fa..c55bfa85 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecLPDDR4.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecLPDDR4.cpp @@ -49,7 +49,6 @@ namespace DRAMSys MemSpecLPDDR4::MemSpecLPDDR4(const Config::MemSpec& memSpec) : MemSpec(memSpec, memSpec.memarchitecturespec.entries.at("nbrOfChannels"), - 1, memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"), 1, diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecSTTMRAM.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecSTTMRAM.cpp index 51070be9..f56abcbb 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecSTTMRAM.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecSTTMRAM.cpp @@ -49,7 +49,6 @@ namespace DRAMSys MemSpecSTTMRAM::MemSpecSTTMRAM(const Config::MemSpec& memSpec) : MemSpec(memSpec, memSpec.memarchitecturespec.entries.at("nbrOfChannels"), - 1, memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"), 1, diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO.cpp index 042fd130..b89b9162 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO.cpp @@ -49,7 +49,6 @@ namespace DRAMSys MemSpecWideIO::MemSpecWideIO(const Config::MemSpec& memSpec) : MemSpec(memSpec, memSpec.memarchitecturespec.entries.at("nbrOfChannels"), - 1, memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"), 1, diff --git a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO2.cpp b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO2.cpp index 3fc327ce..c7f89431 100644 --- a/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO2.cpp +++ b/src/libdramsys/DRAMSys/configuration/memspec/MemSpecWideIO2.cpp @@ -49,7 +49,6 @@ namespace DRAMSys MemSpecWideIO2::MemSpecWideIO2(const Config::MemSpec& memSpec) : MemSpec(memSpec, memSpec.memarchitecturespec.entries.at("nbrOfChannels"), - 1, memSpec.memarchitecturespec.entries.at("nbrOfRanks"), memSpec.memarchitecturespec.entries.at("nbrOfBanks"), 1, diff --git a/src/libdramsys/DRAMSys/controller/Controller.cpp b/src/libdramsys/DRAMSys/controller/Controller.cpp index 99aa20cf..54cef3bf 100644 --- a/src/libdramsys/DRAMSys/controller/Controller.cpp +++ b/src/libdramsys/DRAMSys/controller/Controller.cpp @@ -64,6 +64,9 @@ #include "DRAMSys/controller/scheduler/SchedulerFrFcfsGrp.h" #include "DRAMSys/controller/scheduler/SchedulerGrpFrFcfs.h" #include "DRAMSys/controller/scheduler/SchedulerGrpFrFcfsWm.h" +#include +#include +#include #ifdef DDR5_SIM #include "DRAMSys/controller/checker/CheckerDDR5.h" @@ -89,6 +92,7 @@ Controller::Controller(const sc_module_name& name, config(config), memSpec(memSpec), addressDecoder(addressDecoder), + numberOfBeatsServed(memSpec.ranksPerChannel, 0), minBytesPerBurst(memSpec.defaultBytesPerBurst), maxBytesPerBurst(memSpec.maxBytesPerBurst) { @@ -640,8 +644,14 @@ void Controller::manageResponses() if (nextTransInRespQueue != nullptr) { // Ignore ECC requests + // TODO in future, use a tagging mechanism to distinguish between normal, ECC and maybe + // masked requests if (nextTransInRespQueue->get_extension() == nullptr) - numberOfBeatsServed += ControllerExtension::getBurstLength(*nextTransInRespQueue); + { + auto rank = ControllerExtension::getRank(*nextTransInRespQueue); + numberOfBeatsServed[static_cast(rank)] += + ControllerExtension::getBurstLength(*nextTransInRespQueue); + } if (ChildExtension::isChildTrans(*nextTransInRespQueue)) { @@ -780,8 +790,15 @@ void Controller::end_of_simulation() { idleTimeCollector.end(); - sc_core::sc_time activeTime = static_cast(numberOfBeatsServed) / memSpec.dataRate * - memSpec.tCK / memSpec.pseudoChannelsPerChannel; + std::uint64_t totalNumberOfBeatsServed = + std::accumulate(numberOfBeatsServed.begin(), numberOfBeatsServed.end(), 0); + + sc_core::sc_time activeTime = + static_cast(totalNumberOfBeatsServed) / memSpec.dataRate * memSpec.tCK; + + // HBM specific, pseudo channels get averaged + if (memSpec.pseudoChannelMode()) + activeTime /= memSpec.ranksPerChannel; double bandwidth = activeTime / sc_core::sc_time_stamp(); double bandwidthWoIdle = @@ -795,23 +812,59 @@ void Controller::end_of_simulation() // 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); + * memSpec.devicesPerRank); - 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) + // HBM specific, one or two pseudo channels per channel + if (memSpec.pseudoChannelMode()) + maxBandwidth *= memSpec.ranksPerChannel; + + std::cout << std::left << std::setw(24) << name() << std::string(" Total Time: ") + << sc_core::sc_time_stamp().to_string() << std::endl; + std::cout << std::left << std::setw(24) << 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; + + if (memSpec.ranksPerChannel > 1) + { + for (std::size_t i = 0; i < memSpec.ranksPerChannel; i++) + { + std::string baseName = memSpec.pseudoChannelMode() ? "pc" : "ra"; + std::string rankName = "." + baseName + std::to_string(i); + + sc_core::sc_time rankActiveTime = + numberOfBeatsServed[i] * memSpec.tCK / memSpec.dataRate; + double rankBandwidth = rankActiveTime / sc_core::sc_time_stamp(); + + double rankMaxBandwidth = ( + // 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); + + std::string componentName = name() + rankName; + + std::cout << std::left << std::setw(24) << componentName + << std::string(" AVG BW: ") << std::fixed << std::setprecision(2) + << std::setw(6) << (rankBandwidth * rankMaxBandwidth) << " Gb/s | " + << std::setw(6) << (rankBandwidth * rankMaxBandwidth / 8) << " GB/s | " + << std::setw(6) << (rankBandwidth * 100) << " %" << std::endl; + } + } + + std::cout << std::left << std::setw(24) << 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; + std::cout << std::left << std::setw(24) << 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; } } // namespace DRAMSys diff --git a/src/libdramsys/DRAMSys/controller/Controller.h b/src/libdramsys/DRAMSys/controller/Controller.h index 12bdf697..99e5e622 100644 --- a/src/libdramsys/DRAMSys/controller/Controller.h +++ b/src/libdramsys/DRAMSys/controller/Controller.h @@ -101,7 +101,7 @@ protected: sc_core::sc_time scMaxTime = sc_core::sc_max_time(); - uint64_t numberOfBeatsServed = 0; + std::vector numberOfBeatsServed; unsigned totalNumberOfPayloads = 0; std::function idleCallback; ControllerVector ranksNumberOfPayloads; diff --git a/src/libdramsys/DRAMSys/controller/ControllerRecordable.cpp b/src/libdramsys/DRAMSys/controller/ControllerRecordable.cpp index 8ff5b296..20d5f602 100644 --- a/src/libdramsys/DRAMSys/controller/ControllerRecordable.cpp +++ b/src/libdramsys/DRAMSys/controller/ControllerRecordable.cpp @@ -113,12 +113,14 @@ void ControllerRecordable::controllerMethod() Controller::controllerMethod(); - uint64_t windowNumberOfBeatsServed = numberOfBeatsServed - lastNumberOfBeatsServed; - lastNumberOfBeatsServed = numberOfBeatsServed; + std::uint64_t totalNumberOfBeatsServed = std::accumulate(numberOfBeatsServed.begin(), numberOfBeatsServed.end(), 0); - // FIX: HBM pseudo-channels - // maybe better solution in the future? - windowNumberOfBeatsServed /= memSpec.pseudoChannelsPerChannel; + uint64_t windowNumberOfBeatsServed = totalNumberOfBeatsServed - lastNumberOfBeatsServed; + lastNumberOfBeatsServed = totalNumberOfBeatsServed; + + // HBM specific, pseudo channels get averaged + if (memSpec.pseudoChannelMode()) + windowNumberOfBeatsServed /= memSpec.ranksPerChannel; sc_time windowActiveTime = activeTimeMultiplier * static_cast(windowNumberOfBeatsServed);