diff --git a/DRAMSys/library/src/common/TlmRecorder.cpp b/DRAMSys/library/src/common/TlmRecorder.cpp index 8f410f03..d6174ff5 100644 --- a/DRAMSys/library/src/common/TlmRecorder.cpp +++ b/DRAMSys/library/src/common/TlmRecorder.cpp @@ -35,6 +35,7 @@ * Matthias Jung * Eder F. Zulian * Derek Christ + * Lukas Steiner */ #include @@ -70,7 +71,7 @@ TlmRecorder::TlmRecorder(const std::string &name, const std::string &dbName) : PRINTDEBUGMESSAGE(name, "Starting new database transaction"); } -TlmRecorder::~TlmRecorder() +void TlmRecorder::finalize() { if (db) closeConnection(); diff --git a/DRAMSys/library/src/common/TlmRecorder.h b/DRAMSys/library/src/common/TlmRecorder.h index 6b92859d..dabe3ec5 100644 --- a/DRAMSys/library/src/common/TlmRecorder.h +++ b/DRAMSys/library/src/common/TlmRecorder.h @@ -34,6 +34,7 @@ * Robert Gernhardt * Matthias Jung * Eder F. Zulian + * Lukas Steiner */ #ifndef TLMRECORDER_H @@ -54,7 +55,8 @@ class TlmRecorder { public: TlmRecorder(const std::string &name, const std::string &dbName); - ~TlmRecorder(); + TlmRecorder(const TlmRecorder&) = delete; + TlmRecorder(TlmRecorder&&) = default; void recordMcConfig(std::string _mcconfig) { @@ -78,7 +80,7 @@ public: void recordDebugMessage(const std::string &message, const sc_core::sc_time &time); void updateDataStrobe(const sc_core::sc_time &begin, const sc_core::sc_time &end, tlm::tlm_generic_payload &trans); - void closeConnection(); + void finalize(); private: struct Transaction @@ -113,6 +115,7 @@ private: static void executeSqlStatement(sqlite3_stmt *statement); void openDB(const std::string &dbName); + void closeConnection(); void introduceTransactionSystem(tlm::tlm_generic_payload &trans); void removeTransactionFromSystem(tlm::tlm_generic_payload &trans); diff --git a/DRAMSys/library/src/common/configuration/SimConfig.cpp b/DRAMSys/library/src/common/configuration/SimConfig.cpp index 3459e64c..e0894a78 100644 --- a/DRAMSys/library/src/common/configuration/SimConfig.cpp +++ b/DRAMSys/library/src/common/configuration/SimConfig.cpp @@ -44,7 +44,6 @@ void to_json(json &j, const SimConfig &c) {"CheckTLM2Protocol", c.checkTLM2Protocol}, {"DatabaseRecording", c.databaseRecording}, {"Debug", c.debug}, - {"ECCControllerMode", c.eccControllerMode}, {"EnableWindowing", c.enableWindowing}, {"ErrorCSVFile", c.errorCsvFile}, {"ErrorChipSeed", c.errorChipSeed}, @@ -73,9 +72,6 @@ void from_json(const json &j, SimConfig &c) if (j_simconfig.contains("Debug")) j_simconfig.at("Debug").get_to(c.debug); - if (j_simconfig.contains("ECCControllerMode")) - j_simconfig.at("ECCControllerMode").get_to(c.eccControllerMode); - if (j_simconfig.contains("EnableWindowing")) j_simconfig.at("EnableWindowing").get_to(c.enableWindowing); @@ -106,7 +102,6 @@ void from_json(const json &j, SimConfig &c) if (j_simconfig.contains("WindowSize")) j_simconfig.at("WindowSize").get_to(c.windowSize); - invalidateEnum(c.eccControllerMode); invalidateEnum(c.storeMode); } diff --git a/DRAMSys/library/src/common/configuration/SimConfig.h b/DRAMSys/library/src/common/configuration/SimConfig.h index f9bbbedd..fb5688a3 100644 --- a/DRAMSys/library/src/common/configuration/SimConfig.h +++ b/DRAMSys/library/src/common/configuration/SimConfig.h @@ -46,17 +46,6 @@ using json = nlohmann::json; const std::string simConfigPath = "configs/simulator"; -enum class ECCControllerMode -{ - Disabled, - Hamming, - Invalid = -1 -}; - -NLOHMANN_JSON_SERIALIZE_ENUM(ECCControllerMode, {{ECCControllerMode::Invalid, nullptr}, - {ECCControllerMode::Disabled, "Disabled"}, - {ECCControllerMode::Hamming, "Hamming"}}) - enum class StoreMode { NoStorage, @@ -76,7 +65,6 @@ struct SimConfig Optional checkTLM2Protocol; Optional databaseRecording; Optional debug; - Optional eccControllerMode; Optional enableWindowing; Optional errorCsvFile; Optional errorChipSeed; diff --git a/DRAMSys/library/src/common/configuration/TraceSetup.cpp b/DRAMSys/library/src/common/configuration/TraceSetup.cpp index c5bb2492..19241e33 100644 --- a/DRAMSys/library/src/common/configuration/TraceSetup.cpp +++ b/DRAMSys/library/src/common/configuration/TraceSetup.cpp @@ -59,6 +59,7 @@ void to_json(json &j, const TraceSetup &c) initiator_j["clkMhz"] = initiator->clkMhz; initiator_j["maxPendingReadRequests"] = initiator->maxPendingReadRequests; initiator_j["maxPendingWriteRequests"] = initiator->maxPendingWriteRequests; + initiator_j["addLengthConverter"] = initiator->addLengthConverter; if (const auto generator = dynamic_cast(initiator.get())) { @@ -264,6 +265,9 @@ void from_json(const json &j, TraceSetup &c) if (initiator_j.contains("maxPendingWriteRequests")) initiator_j.at("maxPendingWriteRequests").get_to(initiator->maxPendingWriteRequests); + if (initiator_j.contains("addLengthConverter")) + initiator_j.at("addLengthConverter").get_to(initiator->addLengthConverter); + c.initiators.emplace_back(std::move(initiator)); } } diff --git a/DRAMSys/library/src/common/configuration/TraceSetup.h b/DRAMSys/library/src/common/configuration/TraceSetup.h index 5b61fef0..20cbbd7b 100644 --- a/DRAMSys/library/src/common/configuration/TraceSetup.h +++ b/DRAMSys/library/src/common/configuration/TraceSetup.h @@ -77,6 +77,7 @@ struct TrafficInitiator std::string name; Optional maxPendingReadRequests; Optional maxPendingWriteRequests; + Optional addLengthConverter; }; struct TracePlayer : public TrafficInitiator diff --git a/DRAMSys/library/src/common/dramExtensions.h b/DRAMSys/library/src/common/dramExtensions.h index f4a4a040..dd781871 100644 --- a/DRAMSys/library/src/common/dramExtensions.h +++ b/DRAMSys/library/src/common/dramExtensions.h @@ -163,7 +163,6 @@ public: BankGroup bankGroup, Bank bank, Row row, Column column, unsigned int burstLength, uint64_t threadPayloadID, uint64_t channelPayloadID); - tlm::tlm_extension_base *clone() const override; void copy_from(const tlm::tlm_extension_base &ext) override; diff --git a/DRAMSys/library/src/common/utils.cpp b/DRAMSys/library/src/common/utils.cpp index 11cef417..08e7fa02 100644 --- a/DRAMSys/library/src/common/utils.cpp +++ b/DRAMSys/library/src/common/utils.cpp @@ -80,7 +80,7 @@ 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); - payload.set_extension(new DramExtension(Thread(UINT_MAX), Channel(0), rank, bankGroup, - bank, Row(0), Column(0), 0, 0, channelPayloadID)); + payload.set_extension(new DramExtension(Thread(UINT_MAX), Channel(0), rank, bankGroup, bank, Row(0), Column(0), + 0, 0, channelPayloadID)); payload.set_extension(new GenerationExtension(SC_ZERO_TIME)); } diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index d7915697..cd80dd27 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -39,8 +39,6 @@ * Derek Christ */ -#include - #include "Configuration.h" #include "memspec/MemSpecDDR3.h" #include "memspec/MemSpecDDR4.h" @@ -78,19 +76,6 @@ enum sc_time_unit string2TimeUnit(const std::string &s) } } -// Changes the number of bytes depeding on the ECC Controller. This function is needed for modules which get data directly or indirectly from the ECC Controller -unsigned int Configuration::adjustNumBytesAfterECC(unsigned nBytes) const -{ - // Manipulate the number of bytes only if there is an ECC Controller selected - if (eccMode == ECCMode::Disabled) - return nBytes; - else // if (eccMode == DRAMSysConfiguration::ECCControllerMode::Hamming) - { - assert(pECC != nullptr); - return pECC->AllocationSize(nBytes); - } -} - void Configuration::loadSimConfig(Configuration &config, const DRAMSysConfiguration::SimConfig &simConfig) { if (simConfig.addressOffset.isValid()) @@ -105,16 +90,6 @@ void Configuration::loadSimConfig(Configuration &config, const DRAMSysConfigurat if (simConfig.debug.isValid()) config.debug = simConfig.debug.getValue(); - if (simConfig.eccControllerMode.isValid()) - config.eccMode = [=] { - auto mode = simConfig.eccControllerMode.getValue(); - - if (mode == DRAMSysConfiguration::ECCControllerMode::Disabled) - return ECCMode::Disabled; - else - return ECCMode::Hamming; - }(); - if (simConfig.enableWindowing.isValid()) config.enableWindowing = simConfig.enableWindowing.getValue(); diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index 697b293a..946b48c7 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -46,7 +46,6 @@ #include #include #include "memspec/MemSpec.h" -#include "../error/eccbaseclass.h" #include "TemperatureSimConfig.h" class Configuration @@ -95,8 +94,6 @@ public: bool thermalSimulation = false; bool simulationProgressBar = false; bool checkTLM2Protocol = false; - enum class ECCMode {Disabled, Hamming} eccMode = ECCMode::Disabled; - ECCBaseClass *pECC = nullptr; bool useMalloc = false; unsigned long long int addressOffset = 0; @@ -111,8 +108,6 @@ public: // Temperature Simulation related TemperatureSimConfig temperatureSim; - unsigned int adjustNumBytesAfterECC(unsigned bytes) const; - static void loadMCConfig(Configuration &config, const DRAMSysConfiguration::McConfig &mcConfig); static void loadSimConfig(Configuration &config, const DRAMSysConfiguration::SimConfig &simConfig); static void loadMemSpec(Configuration &config, const DRAMSysConfiguration::MemSpec &memSpec); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp index 99a12c4e..dd455897 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp @@ -56,16 +56,21 @@ MemSpec::MemSpec(const DRAMSysConfiguration::MemSpec &memSpec, numberOfDevices(numberOfDevices), numberOfRows(memSpec.memArchitectureSpec.entries.at("nbrOfRows")), numberOfColumns(memSpec.memArchitectureSpec.entries.at("nbrOfColumns")), - burstLength(memSpec.memArchitectureSpec.entries.at("burstLength")), + defaultBurstLength(memSpec.memArchitectureSpec.entries.at("burstLength")), + maxBurstLength(memSpec.memArchitectureSpec.entries.find("maxBurstLength") != + memSpec.memArchitectureSpec.entries.end() + ? memSpec.memArchitectureSpec.entries.at("maxBurstLength") + : defaultBurstLength), dataRate(memSpec.memArchitectureSpec.entries.at("dataRate")), bitWidth(memSpec.memArchitectureSpec.entries.at("width")), dataBusWidth(bitWidth * numberOfDevices), - bytesPerBurst((burstLength * 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(burstLength) / dataRate)), + burstDuration(tCK * (static_cast(defaultBurstLength) / dataRate)), memorySizeBytes(0) { commandLengthInCycles = std::vector(Command::numberOfCommands(), 1); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index 480b3419..0051705c 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -60,11 +60,13 @@ public: const unsigned numberOfDevices; const unsigned numberOfRows; const unsigned numberOfColumns; - const unsigned burstLength; + const unsigned defaultBurstLength; + const unsigned maxBurstLength; const unsigned dataRate; const unsigned bitWidth; const unsigned dataBusWidth; - const unsigned bytesPerBurst; + const unsigned defaultBytesPerBurst; + const unsigned maxBytesPerBurst; // Clock const double fCKMHz; diff --git a/DRAMSys/library/src/controller/ControllerRecordable.cpp b/DRAMSys/library/src/controller/ControllerRecordable.cpp index 254155e3..eb168cbb 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.cpp +++ b/DRAMSys/library/src/controller/ControllerRecordable.cpp @@ -39,7 +39,7 @@ using namespace sc_core; using namespace tlm; -ControllerRecordable::ControllerRecordable(const sc_module_name &name, TlmRecorder *tlmRecorder) +ControllerRecordable::ControllerRecordable(const sc_module_name &name, TlmRecorder& tlmRecorder) : Controller(name), tlmRecorder(tlmRecorder) { if (Configuration::getInstance().enableWindowing) @@ -78,7 +78,7 @@ void ControllerRecordable::sendToDram(Command command, tlm_generic_payload *payl if (command.isCasCommand()) { TimeInterval dataStrobe = Configuration::getInstance().memSpec->getIntervalOnDataStrobe(command, *payload); - tlmRecorder->updateDataStrobe(sc_time_stamp() + delay + dataStrobe.start, + tlmRecorder.updateDataStrobe(sc_time_stamp() + delay + dataStrobe.start, sc_time_stamp() + delay + dataStrobe.end, *payload); } tlm_phase phase = command.toPhase(); @@ -103,7 +103,7 @@ void ControllerRecordable::recordPhase(tlm_generic_payload &trans, const tlm_pha bg) + " bank " + std::to_string(bank) + " row " + std::to_string(row) + " column " + std::to_string(col) + " id " + std::to_string(id) + " at " + recTime.to_string()); - tlmRecorder->recordPhase(trans, phase, recTime); + tlmRecorder.recordPhase(trans, phase, recTime); } void ControllerRecordable::controllerMethod() @@ -128,7 +128,7 @@ void ControllerRecordable::controllerMethod() slidingAverageBufferDepth[index] = SC_ZERO_TIME; } - tlmRecorder->recordBufferDepth(sc_time_stamp().to_seconds(), windowAverageBufferDepth); + tlmRecorder.recordBufferDepth(sc_time_stamp().to_seconds(), windowAverageBufferDepth); Controller::controllerMethod(); @@ -136,7 +136,7 @@ void ControllerRecordable::controllerMethod() lastNumberOfBeatsServed = numberOfBeatsServed; sc_time windowActiveTime = activeTimeMultiplier * static_cast(windowNumberOfBeatsServed); double windowAverageBandwidth = windowActiveTime / windowSizeTime; - tlmRecorder->recordBandwidth(sc_time_stamp().to_seconds(), windowAverageBandwidth); + tlmRecorder.recordBandwidth(sc_time_stamp().to_seconds(), windowAverageBandwidth); } else { diff --git a/DRAMSys/library/src/controller/ControllerRecordable.h b/DRAMSys/library/src/controller/ControllerRecordable.h index d2300f71..f0f0ae57 100644 --- a/DRAMSys/library/src/controller/ControllerRecordable.h +++ b/DRAMSys/library/src/controller/ControllerRecordable.h @@ -43,7 +43,7 @@ class ControllerRecordable final : public Controller { public: - ControllerRecordable(const sc_core::sc_module_name &name, TlmRecorder *tlmRecorder); + ControllerRecordable(const sc_core::sc_module_name &name, TlmRecorder& tlmRecorder); ~ControllerRecordable() override = default; protected: @@ -59,7 +59,7 @@ protected: private: void recordPhase(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase, const sc_core::sc_time &delay); - TlmRecorder *tlmRecorder; + TlmRecorder& tlmRecorder; sc_core::sc_event windowEvent; sc_core::sc_time windowSizeTime; diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp index 125c6cbf..e8c51245 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR3.cpp @@ -54,7 +54,7 @@ CheckerDDR3::CheckerDDR3() lastCommandOnBus = sc_max_time(); last4Activates = std::vector>(memSpec->numberOfRanks); - tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK; tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL; tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; tWRRD = memSpec->tWL + tBURST + memSpec->tWTR - memSpec->tAL; @@ -75,6 +75,8 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, tlm_generic_paylo if (command == Command::RD || command == Command::RDA) { + assert(DramExtension::getBurstLength(payload) == 8); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); @@ -128,6 +130,8 @@ sc_time CheckerDDR3::timeToSatisfyConstraints(Command command, tlm_generic_paylo } else if (command == Command::WR || command == Command::WRA) { + assert(DramExtension::getBurstLength(payload) == 8); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp index 47b151c7..7ac477d3 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR4.cpp @@ -56,7 +56,7 @@ CheckerDDR4::CheckerDDR4() lastCommandOnBus = sc_max_time(); last4Activates = std::vector>(memSpec->numberOfRanks); - tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK; tRDWR = memSpec->tRL + tBURST + memSpec->tCK - memSpec->tWL + memSpec->tWPRE; tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL + memSpec->tWPRE; tWRRD_S = memSpec->tWL + tBURST + memSpec->tWTR_S - memSpec->tAL; @@ -79,6 +79,8 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, tlm_generic_paylo if (command == Command::RD || command == Command::RDA) { + assert(DramExtension::getBurstLength(payload) == 8); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); @@ -148,6 +150,8 @@ sc_time CheckerDDR4::timeToSatisfyConstraints(Command command, tlm_generic_paylo } else if (command == Command::WR || command == Command::WRA) { + assert(DramExtension::getBurstLength(payload) == 8); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); diff --git a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp index 8a433061..59e55c49 100644 --- a/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerDDR5.cpp @@ -131,7 +131,9 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, tlm_generic_paylo if (command == Command::RD || command == Command::RDA) { unsigned burstLength = DramExtension::getBurstLength(payload); + assert((burstLength == 16) || (burstLength == 32)); assert(!(burstLength == 32) || (memSpec->bitWidth == 4)); + assert(burstLength <= memSpec->maxBurstLength); lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) @@ -316,7 +318,9 @@ sc_time CheckerDDR5::timeToSatisfyConstraints(Command command, tlm_generic_paylo else if (command == Command::WR || command == Command::WRA) { unsigned burstLength = DramExtension::getBurstLength(payload); + assert((burstLength == 16) || (burstLength == 32)); assert(!(burstLength == 32) || (memSpec->bitWidth == 4)); + assert(burstLength <= memSpec->maxBurstLength); lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp index eea58b9c..2f59f86e 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR5.cpp @@ -59,7 +59,7 @@ CheckerGDDR5::CheckerGDDR5() bankwiseRefreshCounter = std::vector(memSpec->numberOfRanks); - tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK; tRDSRE = memSpec->tCL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQO + tBURST; tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQI + tBURST; tRDWR_R = memSpec->tCL + tBURST + memSpec->tRTRS - memSpec->tWL; @@ -80,6 +80,8 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, tlm_generic_payl if (command == Command::RD || command == Command::RDA) { + assert(DramExtension::getBurstLength(payload) == 8); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD); @@ -149,6 +151,8 @@ sc_time CheckerGDDR5::timeToSatisfyConstraints(Command command, tlm_generic_payl } else if (command == Command::WR || command == Command::WRA) { + assert(DramExtension::getBurstLength(payload) == 8); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR); diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp b/DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp index 4f63a8da..5cbfdc6a 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR5X.cpp @@ -59,7 +59,7 @@ CheckerGDDR5X::CheckerGDDR5X() bankwiseRefreshCounter = std::vector(memSpec->numberOfRanks); - tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK; tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQO + tBURST; tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQI + tBURST; tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; @@ -80,6 +80,10 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, tlm_generic_pay if (command == Command::RD || command == Command::RDA) { + unsigned burstLength = DramExtension::getBurstLength(payload); + assert(!(memSpec->dataRate == 4) || (burstLength == 8)); // DDR mode (QDR wrt CK) + assert(!(memSpec->dataRate == 8) || (burstLength == 16)); // QDR mode (ODR wrt CK) + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD); @@ -149,6 +153,10 @@ sc_time CheckerGDDR5X::timeToSatisfyConstraints(Command command, tlm_generic_pay } else if (command == Command::WR || command == Command::WRA) { + unsigned burstLength = DramExtension::getBurstLength(payload); + assert(!(memSpec->dataRate == 4) || (burstLength == 8)); // DDR mode (QDR wrt CK) + assert(!(memSpec->dataRate == 8) || (burstLength == 16)); // QDR mode (ODR wrt CK) + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR); diff --git a/DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp b/DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp index 212982a6..57cf9e9c 100644 --- a/DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerGDDR6.cpp @@ -58,7 +58,7 @@ CheckerGDDR6::CheckerGDDR6() bankwiseRefreshCounter = std::vector(memSpec->numberOfRanks); - tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK; tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQO + tBURST; tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK + memSpec->tWCK2DQI + tBURST; tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; @@ -79,6 +79,8 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, tlm_generic_payl if (command == Command::RD || command == Command::RDA) { + assert(DramExtension::getBurstLength(payload) == 16); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD); @@ -148,6 +150,8 @@ sc_time CheckerGDDR6::timeToSatisfyConstraints(Command command, tlm_generic_payl } else if (command == Command::WR || command == Command::WRA) { + assert(DramExtension::getBurstLength(payload) == 16); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR); diff --git a/DRAMSys/library/src/controller/checker/CheckerHBM2.cpp b/DRAMSys/library/src/controller/checker/CheckerHBM2.cpp index c5866453..dcdbb381 100644 --- a/DRAMSys/library/src/controller/checker/CheckerHBM2.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerHBM2.cpp @@ -59,7 +59,7 @@ CheckerHBM2::CheckerHBM2() bankwiseRefreshCounter = std::vector(memSpec->numberOfRanks); - tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK; tRDPDE = memSpec->tRL + memSpec->tPL + tBURST + memSpec->tCK; tRDSRE = tRDPDE; tWRPRE = memSpec->tWL + tBURST + memSpec->tWR; @@ -80,6 +80,10 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, tlm_generic_paylo if (command == Command::RD || command == Command::RDA) { + unsigned burstLength = DramExtension::getBurstLength(payload); + assert(!(memSpec->numberOfRanks == 1) || (burstLength == 2)); // Legacy mode + assert(!(memSpec->numberOfRanks == 2) || (burstLength == 4)); // Pseudo-channel mode + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDRD + memSpec->tCK); @@ -131,6 +135,10 @@ sc_time CheckerHBM2::timeToSatisfyConstraints(Command command, tlm_generic_paylo } else if (command == Command::WR || command == Command::WRA) { + unsigned burstLength = DramExtension::getBurstLength(payload); + assert(!(memSpec->numberOfRanks == 1) || (burstLength == 2)); // Legacy mode + assert(!(memSpec->numberOfRanks == 2) || (burstLength == 4)); // Pseudo-channel mode + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCDWR + memSpec->tCK); diff --git a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp index 47cef996..1390bc05 100644 --- a/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerLPDDR4.cpp @@ -54,7 +54,7 @@ CheckerLPDDR4::CheckerLPDDR4() lastCommandOnBus = sc_max_time(); last4Activates = std::vector>(memSpec->numberOfRanks); - tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK; tRDWR = memSpec->tRL + memSpec->tDQSCK + tBURST - memSpec->tWL + memSpec->tWPRE + memSpec->tRPST; tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; tWRRD = memSpec->tWL + memSpec->tCK + tBURST + memSpec->tWTR; @@ -81,6 +81,10 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, tlm_generic_pay if (command == Command::RD || command == Command::RDA) { + unsigned burstLength = DramExtension::getBurstLength(payload); + assert((burstLength == 16) || (burstLength == 32)); // TODO: BL16/32 OTF + assert(burstLength <= memSpec->maxBurstLength); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); @@ -130,6 +134,10 @@ sc_time CheckerLPDDR4::timeToSatisfyConstraints(Command command, tlm_generic_pay } else if (command == Command::WR || command == Command::WRA) { + unsigned burstLength = DramExtension::getBurstLength(payload); + assert((burstLength == 16) || (burstLength == 32)); + assert(burstLength <= memSpec->maxBurstLength); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); diff --git a/DRAMSys/library/src/controller/checker/CheckerLPDDR5.cpp b/DRAMSys/library/src/controller/checker/CheckerLPDDR5.cpp index f3d7ead3..194e44cc 100644 --- a/DRAMSys/library/src/controller/checker/CheckerLPDDR5.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerLPDDR5.cpp @@ -84,7 +84,8 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, tlm_generic_pay { unsigned burstLength = DramExtension::getBurstLength(payload); assert(!(memSpec->bitWidth == 8) || (burstLength == 32)); // x8 device -> BL32 - assert(!(memSpec->groupsPerRank > 1) || (burstLength == 16)); // BG mode -> BL16 + assert(!(memSpec->groupsPerRank > 1) || (burstLength == 16)); // BG mode -> BL16 (TODO: BL32) + assert(burstLength <= memSpec->maxBurstLength); lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) @@ -195,7 +196,8 @@ sc_time CheckerLPDDR5::timeToSatisfyConstraints(Command command, tlm_generic_pay { unsigned burstLength = DramExtension::getBurstLength(payload); assert(!(memSpec->bitWidth == 8) || (burstLength == 32)); // x8 device -> BL32 - assert(!(memSpec->groupsPerRank > 1) || (burstLength == 16)); // BG mode -> BL16 + assert(!(memSpec->groupsPerRank > 1) || (burstLength == 16)); // BG mode -> BL16 (TODO: BL32) + assert(burstLength <= memSpec->maxBurstLength); lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) diff --git a/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp index b572c4d3..070b0b42 100644 --- a/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerSTTMRAM.cpp @@ -54,7 +54,7 @@ CheckerSTTMRAM::CheckerSTTMRAM() lastCommandOnBus = sc_max_time(); last4Activates = std::vector>(memSpec->numberOfRanks); - tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK; tRDWR = memSpec->tRL + tBURST + 2 * memSpec->tCK - memSpec->tWL; tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; tWRRD = memSpec->tWL + tBURST + memSpec->tWTR - memSpec->tAL; @@ -75,6 +75,8 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, tlm_generic_pa if (command == Command::RD || command == Command::RDA) { + assert(DramExtension::getBurstLength(payload) == 8); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); @@ -130,6 +132,8 @@ sc_time CheckerSTTMRAM::timeToSatisfyConstraints(Command command, tlm_generic_pa } else if (command == Command::WR || command == Command::WRA) { + assert(DramExtension::getBurstLength(payload) == 8); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD - memSpec->tAL); diff --git a/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp b/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp index c7c526aa..1e441f5c 100644 --- a/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerWideIO.cpp @@ -54,7 +54,7 @@ CheckerWideIO::CheckerWideIO() lastCommandOnBus = sc_max_time(); last2Activates = std::vector>(memSpec->numberOfRanks); - tBURST = memSpec->burstLength * memSpec->tCK; + tBURST = memSpec->defaultBurstLength * memSpec->tCK; tRDWR = memSpec->tRL + tBURST + memSpec->tCK; tRDWR_R = memSpec->tRL + tBURST + memSpec->tRTRS - memSpec->tWL; tWRPRE = memSpec->tWL + tBURST - memSpec->tCK + memSpec->tWR; @@ -75,6 +75,10 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, tlm_generic_pay if (command == Command::RD || command == Command::RDA) { + unsigned burstLength = DramExtension::getBurstLength(payload); + assert((burstLength == 2) || (burstLength == 4)); + assert(burstLength <= memSpec->maxBurstLength); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); @@ -124,6 +128,10 @@ sc_time CheckerWideIO::timeToSatisfyConstraints(Command command, tlm_generic_pay } else if (command == Command::WR || command == Command::WRA) { + unsigned burstLength = DramExtension::getBurstLength(payload); + assert((burstLength == 2) || (burstLength == 4)); + assert(burstLength <= memSpec->maxBurstLength); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); diff --git a/DRAMSys/library/src/controller/checker/CheckerWideIO2.cpp b/DRAMSys/library/src/controller/checker/CheckerWideIO2.cpp index 48cb04f6..182916db 100644 --- a/DRAMSys/library/src/controller/checker/CheckerWideIO2.cpp +++ b/DRAMSys/library/src/controller/checker/CheckerWideIO2.cpp @@ -54,7 +54,7 @@ CheckerWideIO2::CheckerWideIO2() lastCommandOnBus = sc_max_time(); last4Activates = std::vector>(memSpec->numberOfRanks); - tBURST = memSpec->burstLength / memSpec->dataRate * memSpec->tCK; + tBURST = memSpec->defaultBurstLength / memSpec->dataRate * memSpec->tCK; tRDPRE = tBURST + std::max(2 * memSpec->tCK, memSpec->tRTP) - 2 * memSpec->tCK; tRDPDEN = memSpec->tRL + memSpec->tDQSCK + tBURST + memSpec->tCK; tRDWR = memSpec->tRL + memSpec->tDQSCK + tBURST + memSpec->tCK - memSpec->tWL; @@ -76,6 +76,10 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, tlm_generic_pa if (command == Command::RD || command == Command::RDA) { + unsigned burstLength = DramExtension::getBurstLength(payload); + assert((burstLength == 4) || (burstLength == 8)); // TODO: BL4/8 OTF + assert(burstLength <= memSpec->maxBurstLength); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); @@ -125,6 +129,10 @@ sc_time CheckerWideIO2::timeToSatisfyConstraints(Command command, tlm_generic_pa } else if (command == Command::WR || command == Command::WRA) { + unsigned burstLength = DramExtension::getBurstLength(payload); + assert((burstLength == 4) || (burstLength == 8)); + assert(burstLength <= memSpec->maxBurstLength); + lastCommandStart = lastScheduledByCommandAndBank[Command::ACT][bank.ID()]; if (lastCommandStart != sc_max_time()) earliestTimeToStart = std::max(earliestTimeToStart, lastCommandStart + memSpec->tRCD); diff --git a/DRAMSys/library/src/error/errormodel.cpp b/DRAMSys/library/src/error/errormodel.cpp index b44b463d..46537bc1 100644 --- a/DRAMSys/library/src/error/errormodel.cpp +++ b/DRAMSys/library/src/error/errormodel.cpp @@ -53,13 +53,12 @@ void errorModel::init() powerAnalysis = Configuration::getInstance().powerAnalysis; thermalSim = Configuration::getInstance().thermalSimulation; // Get Configuration parameters: - burstLenght = Configuration::getInstance().memSpec->burstLength; + burstLenght = Configuration::getInstance().memSpec->defaultBurstLength; numberOfColumns = Configuration::getInstance().memSpec->numberOfColumns; bytesPerColumn = std::log2(Configuration::getInstance().memSpec->dataBusWidth); // Adjust number of bytes per column dynamically to the selected ecc controller - bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC( - bytesPerColumn); + //TODO: bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC(bytesPerColumn); numberOfRows = Configuration::getInstance().memSpec->numberOfRows; numberOfBitErrorEvents = 0; diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index a771bd2a..5e721fe2 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -72,9 +72,6 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name &name, bool initAndBind) : sc_module(name), tSocket("DRAMSys_tSocket") { - // Initialize ecc pointer - ecc = nullptr; - logo(); // Load config and initialize modules @@ -99,25 +96,6 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name &name, } } -DRAMSys::~DRAMSys() -{ - delete ecc; - - delete arbiter; - - for (auto dram : drams) - delete dram; - - for (auto controller : controllers) - delete controller; - - for (auto tlmChecker : playersTlmCheckers) - delete tlmChecker; - - for (auto tlmChecker : controllersTlmCheckers) - delete tlmChecker; -} - void DRAMSys::logo() { #define GREENTXT(s) std::string(("\u001b[38;5;28m"+std::string((s))+"\033[0m")) @@ -161,69 +139,47 @@ void DRAMSys::instantiateModules(const DRAMSysConfiguration::AddressMapping &add TemperatureController::getInstance(); Configuration &config = Configuration::getInstance(); - // Create new ECC Controller - if (config.eccMode == Configuration::ECCMode::Hamming) - ecc = new ECCHamming("ECCHamming"); - else if (config.eccMode == Configuration::ECCMode::Disabled) - ecc = nullptr; - - // Save ECC Controller into the configuration struct to adjust it dynamically - config.pECC = ecc; - // Create arbiter if (config.arbiter == Configuration::Arbiter::Simple) - arbiter = new ArbiterSimple("arbiter", addressMapping); + arbiter = std::unique_ptr(new ArbiterSimple("arbiter", addressMapping)); else if (config.arbiter == Configuration::Arbiter::Fifo) - arbiter = new ArbiterFifo("arbiter", addressMapping); + arbiter = std::unique_ptr(new ArbiterFifo("arbiter", addressMapping)); else if (config.arbiter == Configuration::Arbiter::Reorder) - arbiter = new ArbiterReorder("arbiter", addressMapping); + arbiter = std::unique_ptr(new ArbiterReorder("arbiter", addressMapping)); // Create controllers and DRAMs MemSpec::MemoryType memoryType = config.memSpec->memoryType; for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++) { - std::string str = "controller" + std::to_string(i); - - ControllerIF *controller = new Controller(str.c_str()); - controllers.push_back(controller); - - str = "dram" + std::to_string(i); - Dram *dram; + controllers.emplace_back(new Controller(("controller" + std::to_string(i)).c_str())); if (memoryType == MemSpec::MemoryType::DDR3) - dram = new DramDDR3(str.c_str()); + drams.emplace_back(new DramDDR3(("dram" + std::to_string(i)).c_str())); else if (memoryType == MemSpec::MemoryType::DDR4) - dram = new DramDDR4(str.c_str()); + drams.emplace_back(new DramDDR4(("dram" + std::to_string(i)).c_str())); else if (memoryType == MemSpec::MemoryType::DDR5) - dram = new DramDDR5(str.c_str()); + drams.emplace_back(new DramDDR5(("dram" + std::to_string(i)).c_str())); else if (memoryType == MemSpec::MemoryType::WideIO) - dram = new DramWideIO(str.c_str()); + drams.emplace_back(new DramWideIO(("dram" + std::to_string(i)).c_str())); else if (memoryType == MemSpec::MemoryType::LPDDR4) - dram = new DramLPDDR4(str.c_str()); + drams.emplace_back(new DramLPDDR4(("dram" + std::to_string(i)).c_str())); else if (memoryType == MemSpec::MemoryType::LPDDR5) - dram = new DramLPDDR5(str.c_str()); + drams.emplace_back(new DramLPDDR5(("dram" + std::to_string(i)).c_str())); else if (memoryType == MemSpec::MemoryType::WideIO2) - dram = new DramWideIO2(str.c_str()); + drams.emplace_back(new DramWideIO2(("dram" + std::to_string(i)).c_str())); else if (memoryType == MemSpec::MemoryType::HBM2) - dram = new DramHBM2(str.c_str()); + drams.emplace_back(new DramHBM2(("dram" + std::to_string(i)).c_str())); else if (memoryType == MemSpec::MemoryType::GDDR5) - dram = new DramGDDR5(str.c_str()); + drams.emplace_back(new DramGDDR5(("dram" + std::to_string(i)).c_str())); else if (memoryType == MemSpec::MemoryType::GDDR5X) - dram = new DramGDDR5X(str.c_str()); + drams.emplace_back(new DramGDDR5X(("dram" + std::to_string(i)).c_str())); else if (memoryType == MemSpec::MemoryType::GDDR6) - dram = new DramGDDR6(str.c_str()); + drams.emplace_back(new DramGDDR6(("dram" + std::to_string(i)).c_str())); else if (memoryType == MemSpec::MemoryType::STTMRAM) - dram = new DramSTTMRAM(str.c_str()); + drams.emplace_back(new DramSTTMRAM(("dram" + std::to_string(i)).c_str())); - drams.push_back(dram); - - if (Configuration::getInstance().checkTLM2Protocol) - { - str = "TLMCheckerController" + std::to_string(i); - tlm_utils::tlm2_base_protocol_checker<> *controllerTlmChecker = - new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); - controllersTlmCheckers.push_back(controllerTlmChecker); - } + if (config.checkTLM2Protocol) + controllersTlmCheckers.push_back(new tlm_utils::tlm2_base_protocol_checker<>(("TlmCheckerController" + std::to_string(i)).c_str())); } } @@ -231,32 +187,20 @@ void DRAMSys::bindSockets() { Configuration &config = Configuration::getInstance(); - // If ECC Controller enabled, put it between Trace and arbiter - if (config.eccMode == Configuration::ECCMode::Hamming) - { - assert(ecc != nullptr); - tSocket.bind(ecc->t_socket); - ecc->i_socket.bind(arbiter->tSocket); - } - else if (config.eccMode == Configuration::ECCMode::Disabled) - tSocket.bind(arbiter->tSocket); + tSocket.bind(arbiter->tSocket); - if (config.checkTLM2Protocol) + for (unsigned i = 0; i < config.memSpec->numberOfChannels; i++) { - for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++) + if (config.checkTLM2Protocol) { arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); controllersTlmCheckers[i]->initiator_socket.bind(controllers[i]->tSocket); - controllers[i]->iSocket.bind(drams[i]->tSocket); } - } - else - { - for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++) + else { arbiter->iSocket.bind(controllers[i]->tSocket); - controllers[i]->iSocket.bind(drams[i]->tSocket); } + controllers[i]->iSocket.bind(drams[i]->tSocket); } } diff --git a/DRAMSys/library/src/simulation/DRAMSys.h b/DRAMSys/library/src/simulation/DRAMSys.h index 8c91baf5..541947ee 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.h +++ b/DRAMSys/library/src/simulation/DRAMSys.h @@ -51,6 +51,8 @@ #include #include #include +#include +#include #include #include @@ -59,46 +61,37 @@ class DRAMSys : public sc_core::sc_module public: tlm_utils::multi_passthrough_target_socket tSocket; - std::vector*> - playersTlmCheckers; - SC_HAS_PROCESS(DRAMSys); DRAMSys(const sc_core::sc_module_name &name, const DRAMSysConfiguration::Configuration &config); - ~DRAMSys() override; - protected: DRAMSys(const sc_core::sc_module_name &name, const DRAMSysConfiguration::Configuration &config, bool initAndBind); //TLM 2.0 Protocol Checkers - std::vector*> - controllersTlmCheckers; - - // All transactions pass first through the ECC Controller - ECCBaseClass *ecc; + std::vector*> controllersTlmCheckers; // TODO: Each DRAM has a reorder buffer (check this!) - ReorderBuffer *reorder; + std::unique_ptr reorder; // All transactions pass through the same arbiter - Arbiter *arbiter; + std::unique_ptr arbiter; // Each DRAM unit has a controller - std::vector controllers; + std::vector> controllers; // DRAM units - std::vector drams; + std::vector> drams; void report(const std::string &message); + void bindSockets(); private: static void logo(); void instantiateModules(const DRAMSysConfiguration::AddressMapping &addressMapping); - void bindSockets(); static void setupDebugManager(const std::string &traceName); }; diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp index fa62d270..6c5ac6b4 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp @@ -76,17 +76,17 @@ DRAMSysRecordable::DRAMSysRecordable(const sc_module_name &name, report(headline); } -DRAMSysRecordable::~DRAMSysRecordable() +void DRAMSysRecordable::end_of_simulation() { // Report power before TLM recorders are deleted if (Configuration::getInstance().powerAnalysis) { - for (auto dram : drams) + for (auto& dram : drams) dram->reportPower(); } - for (auto rec : tlmRecorders) - delete rec; + for (auto& tlmRecorder : tlmRecorders) + tlmRecorder.finalize(); } void DRAMSysRecordable::setupTlmRecorders(const std::string &traceName, const DRAMSysConfiguration::Configuration &configuration) @@ -95,18 +95,12 @@ void DRAMSysRecordable::setupTlmRecorders(const std::string &traceName, const DR for (std::size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) { std::string dbName = traceName + std::string("_ch") + std::to_string(i) + ".tdb"; - std::string recorderName = "tlmRecorder" + std::to_string(i); - TlmRecorder *tlmRecorder = - new TlmRecorder(recorderName, dbName); - tlmRecorder->recordMcConfig(DRAMSysConfiguration::dump(configuration.mcConfig)); - tlmRecorder->recordMemspec(DRAMSysConfiguration::dump(configuration.memSpec)); - - std::string traceNames = Configuration::getInstance().simulationName; - tlmRecorder->recordTraceNames(traceNames); - - tlmRecorders.push_back(tlmRecorder); + tlmRecorders.emplace_back(recorderName, dbName); + tlmRecorders.back().recordMcConfig(DRAMSysConfiguration::dump(configuration.mcConfig)); + tlmRecorders.back().recordMemspec(DRAMSysConfiguration::dump(configuration.memSpec)); + tlmRecorders.back().recordTraceNames(Configuration::getInstance().simulationName); } } @@ -123,101 +117,47 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, // They need to be ready before creating some modules. setupTlmRecorders(traceName, configuration); - // Create new ECC Controller - if (config.eccMode == Configuration::ECCMode::Hamming) - ecc = new ECCHamming("ECCHamming"); - else if (config.eccMode == Configuration::ECCMode::Disabled) - ecc = nullptr; - - // Save ECC Controller into the configuration struct to adjust it dynamically - config.pECC = ecc; - // Create arbiter if (config.arbiter == Configuration::Arbiter::Simple) - arbiter = new ArbiterSimple("arbiter", configuration.addressMapping); + arbiter = std::unique_ptr(new ArbiterSimple("arbiter", configuration.addressMapping)); else if (config.arbiter == Configuration::Arbiter::Fifo) - arbiter = new ArbiterFifo("arbiter", configuration.addressMapping); + arbiter = std::unique_ptr(new ArbiterFifo("arbiter", configuration.addressMapping)); else if (config.arbiter == Configuration::Arbiter::Reorder) - arbiter = new ArbiterReorder("arbiter", configuration.addressMapping); + arbiter = std::unique_ptr(new ArbiterReorder("arbiter", configuration.addressMapping)); // Create controllers and DRAMs MemSpec::MemoryType memoryType = config.memSpec->memoryType; for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++) { - std::string str = "controller" + std::to_string(i); - - ControllerIF *controller = new ControllerRecordable(str.c_str(), tlmRecorders[i]); - controllers.push_back(controller); - - str = "dram" + std::to_string(i); - Dram *dram; + controllers.emplace_back(new ControllerRecordable(("controller" + std::to_string(i)).c_str(), tlmRecorders[i])); if (memoryType == MemSpec::MemoryType::DDR3) - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + drams.emplace_back(new DramRecordable(("dram" + std::to_string(i)).c_str(), tlmRecorders[i])); else if (memoryType == MemSpec::MemoryType::DDR4) - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + drams.emplace_back(new DramRecordable(("dram" + std::to_string(i)).c_str(), tlmRecorders[i])); else if (memoryType == MemSpec::MemoryType::DDR5) - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + drams.emplace_back(new DramRecordable(("dram" + std::to_string(i)).c_str(), tlmRecorders[i])); else if (memoryType == MemSpec::MemoryType::WideIO) - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + drams.emplace_back(new DramRecordable(("dram" + std::to_string(i)).c_str(), tlmRecorders[i])); else if (memoryType == MemSpec::MemoryType::LPDDR4) - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + drams.emplace_back(new DramRecordable(("dram" + std::to_string(i)).c_str(), tlmRecorders[i])); else if (memoryType == MemSpec::MemoryType::LPDDR5) - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + drams.emplace_back(new DramRecordable(("dram" + std::to_string(i)).c_str(), tlmRecorders[i])); else if (memoryType == MemSpec::MemoryType::WideIO2) - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + drams.emplace_back(new DramRecordable(("dram" + std::to_string(i)).c_str(), tlmRecorders[i])); else if (memoryType == MemSpec::MemoryType::HBM2) - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + drams.emplace_back(new DramRecordable(("dram" + std::to_string(i)).c_str(), tlmRecorders[i])); else if (memoryType == MemSpec::MemoryType::GDDR5) - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + drams.emplace_back(new DramRecordable(("dram" + std::to_string(i)).c_str(), tlmRecorders[i])); else if (memoryType == MemSpec::MemoryType::GDDR5X) - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + drams.emplace_back(new DramRecordable(("dram" + std::to_string(i)).c_str(), tlmRecorders[i])); else if (memoryType == MemSpec::MemoryType::GDDR6) - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + drams.emplace_back(new DramRecordable(("dram" + std::to_string(i)).c_str(), tlmRecorders[i])); else if (memoryType == MemSpec::MemoryType::STTMRAM) - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - - drams.push_back(dram); + drams.emplace_back(new DramRecordable(("dram" + std::to_string(i)).c_str(), tlmRecorders[i])); if (config.checkTLM2Protocol) - { - str = "TLMCheckerController" + std::to_string(i); - tlm_utils::tlm2_base_protocol_checker<> *controllerTlmChecker = - new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); - controllersTlmCheckers.push_back(controllerTlmChecker); - } - } -} - -void DRAMSysRecordable::bindSockets() -{ - Configuration &config = Configuration::getInstance(); - - // If ECC Controller enabled, put it between Trace and arbiter - if (config.eccMode == Configuration::ECCMode::Hamming) - { - assert(ecc != nullptr); - tSocket.bind(ecc->t_socket); - ecc->i_socket.bind(arbiter->tSocket); - } - else if (config.eccMode == Configuration::ECCMode::Disabled) - tSocket.bind(arbiter->tSocket); - - if (config.checkTLM2Protocol) - { - for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++) - { - arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); - controllersTlmCheckers[i]->initiator_socket.bind(controllers[i]->tSocket); - controllers[i]->iSocket.bind(drams[i]->tSocket); - } - } - else - { - for (std::size_t i = 0; i < config.memSpec->numberOfChannels; i++) - { - arbiter->iSocket.bind(controllers[i]->tSocket); - controllers[i]->iSocket.bind(drams[i]->tSocket); - } + controllersTlmCheckers.emplace_back(new tlm_utils::tlm2_base_protocol_checker<>(("TLMCheckerController" + + std::to_string(i)).c_str())); } } diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.h b/DRAMSys/library/src/simulation/DRAMSysRecordable.h index aeb0b387..068bbe8a 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.h +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.h @@ -48,19 +48,18 @@ public: DRAMSysRecordable(const sc_core::sc_module_name &name, const DRAMSysConfiguration::Configuration &configuration); - ~DRAMSysRecordable() override; - private: // Transaction Recorders (one per channel). // They generate the output databases. - std::vector tlmRecorders; + std::vector tlmRecorders; + + void end_of_simulation() override; void setupTlmRecorders(const std::string &traceName, const DRAMSysConfiguration::Configuration &configuration); void instantiateModules(const std::string &traceName, const DRAMSysConfiguration::Configuration &configuration); - void bindSockets(); }; #endif // DRAMSYSRECORDABLE_H diff --git a/DRAMSys/library/src/simulation/dram/Dram.cpp b/DRAMSys/library/src/simulation/dram/Dram.cpp index c5c14d28..a578e6af 100644 --- a/DRAMSys/library/src/simulation/dram/Dram.cpp +++ b/DRAMSys/library/src/simulation/dram/Dram.cpp @@ -65,8 +65,6 @@ using namespace DRAMPower; Dram::Dram(const sc_module_name &name) : sc_module(name), tSocket("socket") { Configuration &config = Configuration::getInstance(); - // Adjust number of bytes per burst dynamically to the selected ecc controller - bytesPerBurst = config.adjustNumBytesAfterECC(bytesPerBurst); storeMode = config.storeMode; diff --git a/DRAMSys/library/src/simulation/dram/Dram.h b/DRAMSys/library/src/simulation/dram/Dram.h index 965f70a4..da7a0ede 100644 --- a/DRAMSys/library/src/simulation/dram/Dram.h +++ b/DRAMSys/library/src/simulation/dram/Dram.h @@ -50,7 +50,6 @@ class Dram : public sc_core::sc_module { private: - unsigned int bytesPerBurst = Configuration::getInstance().memSpec->bytesPerBurst; bool powerReported = false; protected: diff --git a/DRAMSys/library/src/simulation/dram/DramDDR3.cpp b/DRAMSys/library/src/simulation/dram/DramDDR3.cpp index 4b1cf98d..347fd817 100644 --- a/DRAMSys/library/src/simulation/dram/DramDDR3.cpp +++ b/DRAMSys/library/src/simulation/dram/DramDDR3.cpp @@ -53,7 +53,7 @@ DramDDR3::DramDDR3(const sc_module_name &name) : Dram(name) SC_REPORT_FATAL("DramDDR3", "Wrong MemSpec chosen"); MemArchitectureSpec memArchSpec; - memArchSpec.burstLength = memSpec->burstLength; + memArchSpec.burstLength = memSpec->defaultBurstLength; memArchSpec.dataRate = memSpec->dataRate; memArchSpec.nbrOfRows = memSpec->numberOfRows; memArchSpec.nbrOfBanks = memSpec->numberOfBanks; diff --git a/DRAMSys/library/src/simulation/dram/DramDDR4.cpp b/DRAMSys/library/src/simulation/dram/DramDDR4.cpp index 58b0970e..cbd5454f 100644 --- a/DRAMSys/library/src/simulation/dram/DramDDR4.cpp +++ b/DRAMSys/library/src/simulation/dram/DramDDR4.cpp @@ -53,7 +53,7 @@ DramDDR4::DramDDR4(const sc_module_name &name) : Dram(name) SC_REPORT_FATAL("DramDDR4", "Wrong MemSpec chosen"); MemArchitectureSpec memArchSpec; - memArchSpec.burstLength = memSpec->burstLength; + memArchSpec.burstLength = memSpec->defaultBurstLength; memArchSpec.dataRate = memSpec->dataRate; memArchSpec.nbrOfRows = memSpec->numberOfRows; memArchSpec.nbrOfBanks = memSpec->numberOfBanks; diff --git a/DRAMSys/library/src/simulation/dram/DramRecordable.cpp b/DRAMSys/library/src/simulation/dram/DramRecordable.cpp index 0638adb3..330d868c 100644 --- a/DRAMSys/library/src/simulation/dram/DramRecordable.cpp +++ b/DRAMSys/library/src/simulation/dram/DramRecordable.cpp @@ -55,7 +55,7 @@ using namespace sc_core; using namespace tlm; template -DramRecordable::DramRecordable(const sc_module_name &name, TlmRecorder *tlmRecorder) +DramRecordable::DramRecordable(const sc_module_name &name, TlmRecorder& tlmRecorder) : BaseDram(name), tlmRecorder(tlmRecorder) { // Create a thread that is triggered every $powerWindowSize @@ -68,7 +68,7 @@ template void DramRecordable::reportPower() { BaseDram::reportPower(); - tlmRecorder->recordPower(sc_time_stamp().to_seconds(), + tlmRecorder.recordPower(sc_time_stamp().to_seconds(), this->DRAMPower->getPower().window_average_power * Configuration::getInstance().memSpec->numberOfDevices); } @@ -103,12 +103,12 @@ void DramRecordable::recordPhase(tlm_generic_payload &trans, const tlm bg) + " bank " + std::to_string(bank) + " row " + std::to_string(row) + " column " + std::to_string(col) + " at " + recTime.to_string()); - tlmRecorder->recordPhase(trans, phase, recTime); + tlmRecorder.recordPhase(trans, phase, recTime); if (phaseNeedsEnd(phase)) { recTime += this->memSpec->getExecutionTime(Command(phase), trans); - tlmRecorder->recordPhase(trans, getEndPhase(phase), recTime); + tlmRecorder.recordPhase(trans, getEndPhase(phase), recTime); } } @@ -134,7 +134,7 @@ void DramRecordable::powerWindow() assert(!isEqual(this->DRAMPower->getEnergy().window_energy, 0.0)); // Store the time (in seconds) and the current average power (in mW) into the database - tlmRecorder->recordPower(sc_time_stamp().to_seconds(), + tlmRecorder.recordPower(sc_time_stamp().to_seconds(), this->DRAMPower->getPower().window_average_power * Configuration::getInstance().memSpec->numberOfDevices); diff --git a/DRAMSys/library/src/simulation/dram/DramRecordable.h b/DRAMSys/library/src/simulation/dram/DramRecordable.h index 4e456536..02dff955 100644 --- a/DRAMSys/library/src/simulation/dram/DramRecordable.h +++ b/DRAMSys/library/src/simulation/dram/DramRecordable.h @@ -46,7 +46,7 @@ template class DramRecordable final : public BaseDram { public: - DramRecordable(const sc_core::sc_module_name &name, TlmRecorder *); + DramRecordable(const sc_core::sc_module_name &name, TlmRecorder& tlmRecorder); SC_HAS_PROCESS(DramRecordable); void reportPower() override; @@ -57,7 +57,7 @@ private: void recordPhase(tlm::tlm_generic_payload &trans, const tlm::tlm_phase &phase, const sc_core::sc_time &delay); - TlmRecorder *tlmRecorder; + TlmRecorder& tlmRecorder; sc_core::sc_time powerWindowSize = Configuration::getInstance().memSpec->tCK * Configuration::getInstance().windowSize; diff --git a/DRAMSys/library/src/simulation/dram/DramWideIO.cpp b/DRAMSys/library/src/simulation/dram/DramWideIO.cpp index 663f063d..dacd5ace 100644 --- a/DRAMSys/library/src/simulation/dram/DramWideIO.cpp +++ b/DRAMSys/library/src/simulation/dram/DramWideIO.cpp @@ -54,7 +54,7 @@ DramWideIO::DramWideIO(const sc_module_name &name) : Dram(name) SC_REPORT_FATAL("DramWideIO", "Wrong MemSpec chosen"); MemArchitectureSpec memArchSpec; - memArchSpec.burstLength = memSpec->burstLength; + memArchSpec.burstLength = memSpec->defaultBurstLength; memArchSpec.dataRate = memSpec->dataRate; memArchSpec.nbrOfRows = memSpec->numberOfRows; memArchSpec.nbrOfBanks = memSpec->numberOfBanks; @@ -74,9 +74,9 @@ DramWideIO::DramWideIO(const sc_module_name &name) : Dram(name) //FIXME: memTimingSpec.RRDB_L = memSpec->tRRD / memSpec->tCK; //FIXME: memTimingSpec.RRDB_S = memSpec->tRRD / memSpec->tCK; memTimingSpec.AL = 0; - memTimingSpec.CCD = memSpec->burstLength; - memTimingSpec.CCD_L = memSpec->burstLength; - memTimingSpec.CCD_S = memSpec->burstLength; + memTimingSpec.CCD = memSpec->defaultBurstLength; + memTimingSpec.CCD_L = memSpec->defaultBurstLength; + memTimingSpec.CCD_S = memSpec->defaultBurstLength; memTimingSpec.CKE = memSpec->tCKE / memSpec->tCK; memTimingSpec.CKESR = memSpec->tCKESR / memSpec->tCK; memTimingSpec.clkMhz = memSpec->fCKMHz; @@ -94,7 +94,7 @@ DramWideIO::DramWideIO(const sc_module_name &name) : Dram(name) memTimingSpec.RRD = memSpec->tRRD / memSpec->tCK; memTimingSpec.RRD_L = memSpec->tRRD / memSpec->tCK; memTimingSpec.RRD_S = memSpec->tRRD / memSpec->tCK; - memTimingSpec.RTP = memSpec->burstLength; + memTimingSpec.RTP = memSpec->defaultBurstLength; memTimingSpec.TAW = memSpec->tTAW / memSpec->tCK; memTimingSpec.WL = memSpec->tWL / memSpec->tCK; memTimingSpec.WR = memSpec->tWR / memSpec->tCK; diff --git a/DRAMSys/simulator/CMakeLists.txt b/DRAMSys/simulator/CMakeLists.txt index a938367c..43b59dd2 100644 --- a/DRAMSys/simulator/CMakeLists.txt +++ b/DRAMSys/simulator/CMakeLists.txt @@ -52,6 +52,7 @@ add_executable(DRAMSys TrafficGenerator.cpp TrafficInitiator.cpp TraceSetup.cpp + LengthConverter.cpp ) if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../library/src/simulation/DRAMSysRecordable.cpp) diff --git a/DRAMSys/simulator/LengthConverter.cpp b/DRAMSys/simulator/LengthConverter.cpp new file mode 100644 index 00000000..b4d8a571 --- /dev/null +++ b/DRAMSys/simulator/LengthConverter.cpp @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2022, Technische Universität Kaiserslautern + * 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 + */ + +#include "LengthConverter.h" + +using namespace sc_core; +using namespace tlm; + +// TODO: return status, TLM_INCOMPLETE_RESPONSE, acquire + release + +LengthConverter::LengthConverter(const sc_module_name &name, unsigned maxOutputLength, bool storageEnabled) : + sc_module(name), payloadEventQueue(this, &LengthConverter::peqCallback), storageEnabled(storageEnabled), + memoryManager(storageEnabled, maxOutputLength), maxOutputLength(maxOutputLength) +{ + iSocket.register_nb_transport_bw(this, &LengthConverter::nb_transport_bw); + tSocket.register_nb_transport_fw(this, &LengthConverter::nb_transport_fw); + tSocket.register_transport_dbg(this, &LengthConverter::transport_dbg); +} + +tlm_sync_enum LengthConverter::nb_transport_fw(tlm_generic_payload& trans, + tlm_phase& phase, sc_time& fwDelay) +{ + if (phase == BEGIN_REQ) + trans.acquire(); + + payloadEventQueue.notify(trans, phase, fwDelay); + return TLM_ACCEPTED; +} + +tlm_sync_enum LengthConverter::nb_transport_bw(tlm_generic_payload &payload, + tlm_phase &phase, sc_time &bwDelay) +{ + payloadEventQueue.notify(payload, phase, bwDelay); + return TLM_ACCEPTED; +} + +unsigned int LengthConverter::transport_dbg(tlm_generic_payload &trans) +{ + return iSocket->transport_dbg(trans); +} + +void LengthConverter::peqCallback(tlm_generic_payload &cbTrans, const tlm_phase &cbPhase) +{ + if (cbPhase == BEGIN_REQ) // from initiator + { + if (cbTrans.get_data_length() <= maxOutputLength) + { + // pipe transaction through + tlm_phase fwPhase = BEGIN_REQ; + sc_time fwDelay = SC_ZERO_TIME; + tlm_sync_enum returnStatus = iSocket->nb_transport_fw(cbTrans, fwPhase, fwDelay); + // TODO: END_REQ/BEGIN_RESP shortcut + } + else + { + // split transaction up into multiple sub-transactions + createChildTranses(&cbTrans); + tlm_generic_payload* firstChildTrans = cbTrans.get_extension()->getNextChildTrans(); + tlm_phase fwPhase = BEGIN_REQ; + sc_time fwDelay = SC_ZERO_TIME; + tlm_sync_enum returnStatus = iSocket->nb_transport_fw(*firstChildTrans, fwPhase, fwDelay); + } + } + else if (cbPhase == END_REQ) + { + if (ChildExtension::isChildTrans(&cbTrans)) + { + tlm_generic_payload* nextChildTrans = cbTrans.get_extension()->getNextChildTrans(); + if (nextChildTrans != nullptr) + { + tlm_phase fwPhase = BEGIN_REQ; + //sc_time fwDelay = SC_ZERO_TIME; + sc_time fwDelay = sc_time(1, SC_NS); + tlm_sync_enum returnStatus = iSocket->nb_transport_fw(*nextChildTrans, fwPhase, fwDelay); + } + else + { + tlm_generic_payload* parentTrans = cbTrans.get_extension()->getParentTrans(); + tlm_phase bwPhase = END_REQ; + sc_time bwDelay = SC_ZERO_TIME; + tlm_sync_enum returnStatus = tSocket->nb_transport_bw(*parentTrans, bwPhase, bwDelay); + } + } + else + { + tlm_phase bwPhase = END_REQ; + sc_time bwDelay = SC_ZERO_TIME; + tlm_sync_enum returnStatus = tSocket->nb_transport_bw(cbTrans, bwPhase, bwDelay); + } + } + else if (cbPhase == BEGIN_RESP) + { + if (ChildExtension::isChildTrans(&cbTrans)) + { + { + tlm_phase fwPhase = END_RESP; + sc_time fwDelay = SC_ZERO_TIME; + tlm_sync_enum returnStatus = iSocket->nb_transport_fw(cbTrans, fwPhase, fwDelay); + } + + if (storageEnabled && cbTrans.is_read()) + { + tlm_generic_payload* parentTrans = cbTrans.get_extension()->getParentTrans(); + std::copy(cbTrans.get_data_ptr(), cbTrans.get_data_ptr() + maxOutputLength, + parentTrans->get_data_ptr() + (cbTrans.get_address() - parentTrans->get_address())); + } + + if (cbTrans.get_extension()->notifyChildTransCompletion()) // all children finished + { + // BEGIN_RESP über tSocket + tlm_generic_payload* parentTrans = cbTrans.get_extension()->getParentTrans(); + tlm_phase bwPhase = BEGIN_RESP; + sc_time bwDelay = SC_ZERO_TIME; + tlm_sync_enum returnStatus = tSocket->nb_transport_bw(*parentTrans, bwPhase, bwDelay); + } + } + else + { + tlm_phase bwPhase = BEGIN_RESP; + sc_time bwDelay = SC_ZERO_TIME; + tlm_sync_enum returnStatus = tSocket->nb_transport_bw(cbTrans, bwPhase, bwDelay); + } + } + else if (cbPhase == END_RESP) + { + if (ParentExtension::isParentTrans(&cbTrans)) + { + cbTrans.get_extension()->releaseChildTranses(); + } + else + { + tlm_phase fwPhase = END_RESP; + sc_time fwDelay = SC_ZERO_TIME; + tlm_sync_enum returnStatus = iSocket->nb_transport_fw(cbTrans, fwPhase, fwDelay); + } + cbTrans.release(); + } + else + SC_REPORT_FATAL(0, "Payload event queue in LengthConverter was triggered with unknown phase"); +} + +void LengthConverter::createChildTranses(tlm_generic_payload* parentTrans) +{ + unsigned numChildTranses = parentTrans->get_data_length() / maxOutputLength; + std::vector childTranses; + + for (unsigned childId = 0; childId < numChildTranses; childId++) + { + tlm_generic_payload* childTrans = memoryManager.allocate(); + childTrans->acquire(); + childTrans->set_command(parentTrans->get_command()); + childTrans->set_address(parentTrans->get_address() + childId * maxOutputLength); + childTrans->set_data_length(maxOutputLength); + if (storageEnabled && parentTrans->is_write()) + std::copy(parentTrans->get_data_ptr() + childId * maxOutputLength, parentTrans->get_data_ptr() + + (childId + 1) * maxOutputLength, childTrans->get_data_ptr()); + ChildExtension::setExtension(childTrans, parentTrans); + childTranses.push_back(childTrans); + } + ParentExtension::setExtension(parentTrans, std::move(childTranses)); +} + +LengthConverter::MemoryManager::MemoryManager(bool storageEnabled, unsigned maxDataLength) + : storageEnabled(storageEnabled), maxDataLength(maxDataLength) +{} + +LengthConverter::MemoryManager::~MemoryManager() +{ + while (!freePayloads.empty()) + { + tlm_generic_payload* payload = freePayloads.top(); + if (storageEnabled) + delete[] payload->get_data_ptr(); + payload->reset(); + delete payload; + freePayloads.pop(); + } +} + +tlm_generic_payload* LengthConverter::MemoryManager::allocate() +{ + if (freePayloads.empty()) + { + auto* payload = new tlm_generic_payload(this); + + if (storageEnabled) + { + auto* data = new unsigned char[maxDataLength]; + payload->set_data_ptr(data); + } + return payload; + } + else + { + tlm_generic_payload* result = freePayloads.top(); + freePayloads.pop(); + return result; + } +} + +void LengthConverter::MemoryManager::free(tlm_generic_payload* payload) +{ + freePayloads.push(payload); +} \ No newline at end of file diff --git a/DRAMSys/simulator/LengthConverter.h b/DRAMSys/simulator/LengthConverter.h new file mode 100644 index 00000000..bac9c29d --- /dev/null +++ b/DRAMSys/simulator/LengthConverter.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2022, Technische Universität Kaiserslautern + * 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 + */ + +#ifndef LENGTHCONVERTER_H +#define LENGTHCONVERTER_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +//TLM_DECLARE_EXTENDED_PHASE(REQ_ARBITRATION); +//TLM_DECLARE_EXTENDED_PHASE(RESP_ARBITRATION); + +class LengthConverter : public sc_core::sc_module +{ +public: + tlm_utils::simple_initiator_socket iSocket; + tlm_utils::simple_target_socket tSocket; + + LengthConverter(const sc_core::sc_module_name& name, unsigned maxOutputLength, bool storageEnabled); + SC_HAS_PROCESS(LengthConverter); + +private: + tlm_utils::peq_with_cb_and_phase payloadEventQueue; + void peqCallback(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase); + + //std::vector tSocketIsBusy; + //std::vector iSocketIsBusy; + + const unsigned maxOutputLength; + const bool storageEnabled; + + void createChildTranses(tlm::tlm_generic_payload* parentTrans); + + //std::uint64_t getTargetAddress(std::uint64_t address) const; + //int getISocketId(std::uint64_t address) const; + + //std::vector> pendingRequests; + + tlm::tlm_sync_enum nb_transport_fw(tlm::tlm_generic_payload &trans, tlm::tlm_phase &phase, + sc_core::sc_time &fwDelay); + tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, + sc_core::sc_time &bwDelay); + unsigned int transport_dbg(tlm::tlm_generic_payload &trans); + + class MemoryManager : public tlm::tlm_mm_interface + { + public: + MemoryManager(bool storageEnabled, unsigned maxDataLength); + ~MemoryManager() override; + tlm::tlm_generic_payload* allocate(); + void free(tlm::tlm_generic_payload* payload) override; + + private: + std::stack freePayloads; + bool storageEnabled = false; + unsigned maxDataLength; + } memoryManager; + + class ChildExtension : public tlm::tlm_extension + { + private: + tlm::tlm_generic_payload* parentTrans; + explicit ChildExtension(tlm::tlm_generic_payload* parentTrans) : parentTrans(parentTrans) {} + + public: + //ChildExtension() = delete; + + tlm_extension_base* clone() const override + { + return new ChildExtension(parentTrans); + } + + void copy_from(tlm_extension_base const &ext) override + { + const auto& cpyFrom = dynamic_cast(ext); + parentTrans = cpyFrom.parentTrans; + } + + tlm::tlm_generic_payload* getParentTrans() + { + return parentTrans; + } + + static void setExtension(tlm::tlm_generic_payload* childTrans, tlm::tlm_generic_payload* parentTrans) + { + auto *extension = childTrans->get_extension(); + + if (extension != nullptr) + { + extension->parentTrans = parentTrans; + } + else + { + extension = new ChildExtension(parentTrans); + childTrans->set_auto_extension(extension); + } + } + + static bool isChildTrans(const tlm::tlm_generic_payload* trans) + { + if (trans->get_extension() != nullptr) + return true; + else + return false; + } + + tlm::tlm_generic_payload* getNextChildTrans() + { + return parentTrans->get_extension()->getNextChildTrans(); + } + + bool notifyChildTransCompletion() + { + return parentTrans->get_extension()->notifyChildTransCompletion(); + } + }; + + class ParentExtension : public tlm::tlm_extension + { + private: + std::vector childTranses; + unsigned nextEndReqChildId = 0; + unsigned completedChildTranses = 0; + explicit ParentExtension(std::vector _childTranses) + : childTranses(std::move(_childTranses)) {} + + public: + ParentExtension() = delete; + + tlm_extension_base* clone() const override + { + return new ParentExtension(childTranses); + } + + void copy_from(tlm_extension_base const &ext) override + { + const auto& cpyFrom = dynamic_cast(ext); + childTranses = cpyFrom.childTranses; + } + + static bool isParentTrans(const tlm::tlm_generic_payload* trans) + { + auto* extension = trans->get_extension(); + if (extension != nullptr) + return !extension->childTranses.empty(); + else + return false; + } + + static void setExtension(tlm::tlm_generic_payload* parentTrans, std::vector childTranses) + { + auto* extension = parentTrans->get_extension(); + + if (extension != nullptr) + { + extension->childTranses = std::move(childTranses); + extension->nextEndReqChildId = 0; + extension->completedChildTranses = 0; + } + else + { + extension = new ParentExtension(std::move(childTranses)); + parentTrans->set_auto_extension(extension); + } + } + + tlm::tlm_generic_payload* getNextChildTrans() + { + if (nextEndReqChildId < childTranses.size()) + return childTranses[nextEndReqChildId++]; + else + return nullptr; + } + + bool notifyChildTransCompletion() + { + completedChildTranses++; + return completedChildTranses == childTranses.size(); + } + + void releaseChildTranses() + { + std::for_each(childTranses.begin(), childTranses.end(), + [](tlm::tlm_generic_payload* childTrans){childTrans->release();}); + childTranses.clear(); + } + }; +}; + +#endif // LENGTHCONVERTER_H diff --git a/DRAMSys/simulator/MemoryManager.cpp b/DRAMSys/simulator/MemoryManager.cpp index ad4036a3..d9f029ee 100644 --- a/DRAMSys/simulator/MemoryManager.cpp +++ b/DRAMSys/simulator/MemoryManager.cpp @@ -51,17 +51,18 @@ MemoryManager::MemoryManager() MemoryManager::~MemoryManager() { - for (tlm_generic_payload *payload : freePayloads) + for (auto& innerBuffer : freePayloads) { - if (storageEnabled) + while (!innerBuffer.second.empty()) { - // Delete data buffer - delete[] payload->get_data_ptr(); + tlm_generic_payload* payload = innerBuffer.second.top(); + if (storageEnabled) + delete[] payload->get_data_ptr(); + payload->reset(); + delete payload; + innerBuffer.second.pop(); + numberOfFrees++; } - // Delete all extensions - payload->reset(); - delete payload; - numberOfFrees++; } // Comment in if you are suspecting a memory leak in the manager @@ -69,18 +70,17 @@ MemoryManager::~MemoryManager() //PRINTDEBUGMESSAGE("MemoryManager","Number of freed payloads: " + to_string(numberOfFrees)); } -tlm_generic_payload *MemoryManager::allocate() +tlm_generic_payload *MemoryManager::allocate(unsigned dataLength) { - if (freePayloads.empty()) + if (freePayloads[dataLength].empty()) { numberOfAllocations++; - tlm_generic_payload *payload = new tlm_generic_payload(this); + auto* payload = new tlm_generic_payload(this); if (storageEnabled) { // Allocate a data buffer and initialize it with zeroes: - unsigned int dataLength = Configuration::getInstance().memSpec->bytesPerBurst; - unsigned char *data = new unsigned char[dataLength]; + auto* data = new unsigned char[dataLength]; std::fill(data, data + dataLength, 0); payload->set_data_ptr(data); } @@ -89,13 +89,14 @@ tlm_generic_payload *MemoryManager::allocate() } else { - tlm_generic_payload *result = freePayloads.back(); - freePayloads.pop_back(); + tlm_generic_payload *result = freePayloads[dataLength].top(); + freePayloads[dataLength].pop(); return result; } } void MemoryManager::free(tlm_generic_payload *payload) { - freePayloads.push_back(payload); + unsigned dataLength = payload->get_data_length(); + freePayloads[dataLength].push(payload); } diff --git a/DRAMSys/simulator/MemoryManager.h b/DRAMSys/simulator/MemoryManager.h index 6a26bee8..6a5dd1ad 100644 --- a/DRAMSys/simulator/MemoryManager.h +++ b/DRAMSys/simulator/MemoryManager.h @@ -37,7 +37,8 @@ #ifndef MEMORYMANAGER_H #define MEMORYMANAGER_H -#include +#include +#include #include @@ -46,13 +47,13 @@ class MemoryManager : public tlm::tlm_mm_interface public: MemoryManager(); ~MemoryManager() override; - tlm::tlm_generic_payload *allocate(); + tlm::tlm_generic_payload *allocate(unsigned dataLength); void free(tlm::tlm_generic_payload *payload) override; private: uint64_t numberOfAllocations; uint64_t numberOfFrees; - std::vector freePayloads; + std::unordered_map> freePayloads; bool storageEnabled = false; }; diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index 7a1a3f5d..de4a1ec7 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -48,9 +48,10 @@ StlPlayer::StlPlayer(const sc_module_name &name, const sc_time &playerClk, unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, + bool addLengthConverter, TraceSetup *setup, bool relative) : - TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests), + TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests, addLengthConverter), file(pathToTrace), relative(relative), playerClk(playerClk) { currentBuffer = &lineContents[0]; @@ -73,9 +74,6 @@ StlPlayer::StlPlayer(const sc_module_name &name, SC_REPORT_FATAL("StlPlayer", "Trace file is empty"); } - burstLength = Configuration::getInstance().memSpec->burstLength; - dataLength = Configuration::getInstance().memSpec->bytesPerBurst; - currentBuffer->reserve(lineBufferSize); parseBuffer->reserve(lineBufferSize); @@ -103,17 +101,16 @@ void StlPlayer::sendNextPayload() } // Allocate a generic payload for this request. - tlm_generic_payload *payload = setup->allocatePayload(); + tlm_generic_payload *payload = setup->allocatePayload(lineIterator->dataLength); payload->acquire(); // Fill up the payload. - payload->set_address(lineIterator->addr); + payload->set_address(lineIterator->address); payload->set_response_status(TLM_INCOMPLETE_RESPONSE); payload->set_dmi_allowed(false); payload->set_byte_enable_length(0); - payload->set_streaming_width(burstLength); - payload->set_data_length(dataLength); - payload->set_command(lineIterator->cmd); + payload->set_data_length(lineIterator->dataLength); + payload->set_command(lineIterator->command); std::copy(lineIterator->data.begin(), lineIterator->data.end(), payload->get_data_ptr()); sc_time sendingTime; @@ -164,64 +161,60 @@ void StlPlayer::parseTraceFile() // Trace files MUST provide timestamp, command and address for every // transaction. The data information depends on the storage mode // configuration. - std::string time, command, address, dataStr; + std::string element; std::istringstream iss; iss.str(line); // Get the timestamp for the transaction. - iss >> time; - if (time.empty()) - SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Timestamp could not be found (line " + std::to_string( - lineCnt) + ").").c_str()); - content.sendingTime = playerClk * static_cast(std::stoull(time)); + iss >> element; + if (element.empty()) + SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); + content.sendingTime = playerClk * static_cast(std::stoull(element)); - // Get the command. - iss >> command; - if (command.empty()) - SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Command could not be found (line " + std::to_string( - lineCnt) + ").").c_str()); - - if (command == "read") - content.cmd = TLM_READ_COMMAND; - else if (command == "write") - content.cmd = TLM_WRITE_COMMAND; + // Get the optional burst length and command + iss >> element; + if (element.empty()) + SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); + if (element.at(0) == '(') + { + element.erase(0, 1); + content.dataLength = std::stoul(element); + iss >> element; + if (element.empty()) + SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); + } else - SC_REPORT_FATAL("StlPlayer", - (std::string("Corrupted tracefile, command ") + command + - std::string(" unknown")).c_str()); + content.dataLength = defaultDataLength; + + if (element == "read") + content.command = TLM_READ_COMMAND; + else if (element == "write") + content.command = TLM_WRITE_COMMAND; + else + SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); // Get the address. - iss >> address; - if (address.empty()) - SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Address could not be found (line " - + std::to_string(lineCnt) + ").").c_str()); - content.addr = std::stoull(address, nullptr, 16); + iss >> element; + if (element.empty()) + SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); + content.address = std::stoull(element, nullptr, 16); // Get the data if necessary. - if (storageEnabled && content.cmd == TLM_WRITE_COMMAND) + if (storageEnabled && content.command == TLM_WRITE_COMMAND) { // The input trace file must provide the data to be stored into the memory. - iss >> dataStr; - if (dataStr.empty()) - SC_REPORT_FATAL("StlPlayer", - ("Malformed trace file. Data information could not be found (line " + std::to_string( - lineCnt) + ").").c_str()); + iss >> element; // Check if data length in the trace file is correct. // We need two characters to represent 1 byte in hexadecimal. Offset for 0x prefix. - if (dataStr.length() != (dataLength * 2 + 2)) - SC_REPORT_FATAL("StlPlayer", - ("Data in the trace file has an invalid length (line " + std::to_string( - lineCnt) + ").").c_str()); + if (element.length() != (content.dataLength * 2 + 2)) + SC_REPORT_FATAL("StlPlayer", ("Malformed trace file line " + std::to_string(lineCnt) + ".").c_str()); // Set data - for (unsigned i = 0; i < dataLength; i++) + for (unsigned i = 0; i < content.dataLength; i++) content.data.emplace_back(static_cast - (std::stoi(dataStr.substr(i * 2 + 2, 2), nullptr, 16))); + (std::stoi(element.substr(i * 2 + 2, 2), nullptr, 16))); } } } diff --git a/DRAMSys/simulator/StlPlayer.h b/DRAMSys/simulator/StlPlayer.h index 976ba318..049c2034 100644 --- a/DRAMSys/simulator/StlPlayer.h +++ b/DRAMSys/simulator/StlPlayer.h @@ -55,8 +55,9 @@ struct LineContent { sc_core::sc_time sendingTime; - tlm::tlm_command cmd; - uint64_t addr; + unsigned dataLength; + tlm::tlm_command command; + uint64_t address; std::vector data; }; @@ -68,6 +69,7 @@ public: const sc_core::sc_time &playerClk, unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, + bool addLengthConverter, TraceSetup *setup, bool relative); diff --git a/DRAMSys/simulator/TraceSetup.cpp b/DRAMSys/simulator/TraceSetup.cpp index 08373c62..7bd468f8 100644 --- a/DRAMSys/simulator/TraceSetup.cpp +++ b/DRAMSys/simulator/TraceSetup.cpp @@ -47,7 +47,7 @@ using namespace tlm; TraceSetup::TraceSetup(const DRAMSysConfiguration::TraceSetup &traceSetup, const std::string &pathToResources, - std::vector &players) + std::vector> &players) { if (traceSetup.initiators.empty()) SC_REPORT_FATAL("TraceSetup", "No traffic initiators specified"); @@ -73,6 +73,13 @@ TraceSetup::TraceSetup(const DRAMSysConfiguration::TraceSetup &traceSetup, return 0; }(); + bool addLengthConverter = [=]() -> bool { + if (inititator->addLengthConverter.isValid()) + return inititator->addLengthConverter.getValue(); + else + return false; + }(); + if (std::dynamic_pointer_cast(inititator)) { size_t pos = name.rfind('.'); @@ -94,20 +101,20 @@ TraceSetup::TraceSetup(const DRAMSysConfiguration::TraceSetup &traceSetup, StlPlayer *player; if (ext == "stl") player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, - maxPendingReadRequests, maxPendingWriteRequests, this, false); + maxPendingReadRequests, maxPendingWriteRequests, addLengthConverter, this, false); else if (ext == "rstl") player = new StlPlayer(moduleName.c_str(), stlFile, playerClk, - maxPendingReadRequests, maxPendingWriteRequests, this, true); + maxPendingReadRequests, maxPendingWriteRequests, addLengthConverter, this, true); else throw std::runtime_error("Unsupported file extension in " + name); - players.push_back(player); + players.push_back(std::unique_ptr(player)); totalTransactions += player->getNumberOfLines(); } else if (auto generator = std::dynamic_pointer_cast(inititator)) { TrafficGenerator *trafficGenerator = new TrafficGenerator(name.c_str(), *generator, this); - players.push_back(trafficGenerator); + players.push_back(std::unique_ptr(trafficGenerator)); totalTransactions += trafficGenerator->getTotalTransactions(); } @@ -116,7 +123,7 @@ TraceSetup::TraceSetup(const DRAMSysConfiguration::TraceSetup &traceSetup, uint64_t numRequests = hammer->numRequests; uint64_t rowIncrement = hammer->rowIncrement; - players.push_back(new TrafficGeneratorHammer(name.c_str(), *hammer, this)); + players.push_back(std::unique_ptr(new TrafficGeneratorHammer(name.c_str(), *hammer, this))); totalTransactions += numRequests; } } @@ -132,16 +139,16 @@ TraceSetup::TraceSetup(const DRAMSysConfiguration::TraceSetup &traceSetup, const std::string name = generatorConf->name; auto listenerIt = std::find_if(players.begin(), players.end(), - [&name](const TrafficInitiator *initiator) { return initiator->name() == name; }); + [&name](const std::unique_ptr &initiator) { return initiator->name() == name; }); // Should be found - auto listener = dynamic_cast(*listenerIt); + auto listener = dynamic_cast(listenerIt->get()); auto notifierIt = std::find_if(players.begin(), players.end(), - [&idleUntil](const TrafficInitiator *initiator) + [&idleUntil](const std::unique_ptr &initiator) { - if (auto generator = dynamic_cast(initiator)) + if (auto generator = dynamic_cast(initiator.get())) { if (generator->hasStateTransitionEvent(idleUntil)) return true; @@ -153,7 +160,7 @@ TraceSetup::TraceSetup(const DRAMSysConfiguration::TraceSetup &traceSetup, if (notifierIt == players.end()) SC_REPORT_FATAL("TraceSetup", "Event to listen on not found."); - auto notifier = dynamic_cast(*notifierIt); + auto notifier = dynamic_cast(notifierIt->get()); listener->waitUntil(¬ifier->getStateTransitionEvent(idleUntil)); } } @@ -161,6 +168,7 @@ TraceSetup::TraceSetup(const DRAMSysConfiguration::TraceSetup &traceSetup, remainingTransactions = totalTransactions; numberOfTrafficInitiators = players.size(); + defaultDataLength = Configuration::getInstance().memSpec->defaultBytesPerBurst; } void TraceSetup::trafficInitiatorTerminates() @@ -181,9 +189,14 @@ void TraceSetup::transactionFinished() std::cout << std::endl; } +tlm_generic_payload *TraceSetup::allocatePayload(unsigned dataLength) +{ + return memoryManager.allocate(dataLength); +} + tlm_generic_payload *TraceSetup::allocatePayload() { - return memoryManager.allocate(); + return allocatePayload(defaultDataLength); } void TraceSetup::loadBar(uint64_t x, uint64_t n, unsigned int w, unsigned int granularity) diff --git a/DRAMSys/simulator/TraceSetup.h b/DRAMSys/simulator/TraceSetup.h index 4ff6e138..6dd60e91 100644 --- a/DRAMSys/simulator/TraceSetup.h +++ b/DRAMSys/simulator/TraceSetup.h @@ -37,9 +37,10 @@ #ifndef TRACESETUP_H #define TRACESETUP_H +#include #include #include -#include +#include #include #include "MemoryManager.h" @@ -51,10 +52,11 @@ class TraceSetup public: TraceSetup(const DRAMSysConfiguration::TraceSetup &traceSetup, const std::string &pathToResources, - std::vector &devices); + std::vector> &devices); void trafficInitiatorTerminates(); void transactionFinished(); + tlm::tlm_generic_payload *allocatePayload(unsigned dataLength); tlm::tlm_generic_payload *allocatePayload(); private: @@ -63,6 +65,7 @@ private: uint64_t remainingTransactions; unsigned int finishedTrafficInitiators = 0; MemoryManager memoryManager; + unsigned defaultDataLength = 64; static void loadBar(uint64_t x, uint64_t n, unsigned int w = 50, unsigned int granularity = 1); }; diff --git a/DRAMSys/simulator/TrafficGenerator.cpp b/DRAMSys/simulator/TrafficGenerator.cpp index 5d15235d..bfca8a46 100644 --- a/DRAMSys/simulator/TrafficGenerator.cpp +++ b/DRAMSys/simulator/TrafficGenerator.cpp @@ -44,11 +44,9 @@ using namespace sc_core; using namespace tlm; TrafficGeneratorIf::TrafficGeneratorIf(const sc_core::sc_module_name &name, TraceSetup *setup, - unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests) - : TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests) + unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, bool addLengthConverter) + : TrafficInitiator(name, setup, maxPendingReadRequests, maxPendingWriteRequests, addLengthConverter) { - burstLength = Configuration::getInstance().memSpec->burstLength; - dataLength = Configuration::getInstance().memSpec->bytesPerBurst; } void TrafficGeneratorIf::sendNextPayload() @@ -75,8 +73,7 @@ void TrafficGeneratorIf::sendNextPayload() payload->set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); payload->set_dmi_allowed(false); payload->set_byte_enable_length(0); - payload->set_streaming_width(burstLength); - payload->set_data_length(dataLength); + payload->set_data_length(defaultDataLength); payload->set_command(command); sc_time generatorClk = getGeneratorClk(); @@ -96,7 +93,7 @@ void TrafficGeneratorIf::sendNextPayload() TrafficGenerator::TrafficGenerator(const sc_module_name &name, const DRAMSysConfiguration::TraceGenerator &conf, TraceSetup *setup) - : TrafficGeneratorIf(name, setup, evaluateMaxPendingReadRequests(conf), evaluateMaxPendingWriteRequests(conf)), + : TrafficGeneratorIf(name, setup, evaluateMaxPendingReadRequests(conf), evaluateMaxPendingWriteRequests(conf), evaluateAddLengthConverter(conf)), generatorClk(TrafficInitiator::evaluateGeneratorClk(conf)), conf(conf), maxTransactions(evaluateMaxTransactions(conf)), randomGenerator(std::default_random_engine(evaluateSeed(conf))) { @@ -366,6 +363,14 @@ uint64_t TrafficGenerator::evaluateMaxTransactions(const DRAMSysConfiguration::T return std::numeric_limits::max(); } +bool TrafficGenerator::evaluateAddLengthConverter(const DRAMSysConfiguration::TraceGenerator &conf) +{ + if (conf.addLengthConverter.isValid()) + return conf.addLengthConverter.getValue(); + else + return false; +} + uint64_t TrafficGenerator::evaluateMinAddress(const DRAMSysConfiguration::TraceGeneratorTrafficState &state) { if (state.minAddress.isValid()) @@ -400,7 +405,7 @@ uint64_t TrafficGenerator::evaluateClksPerRequest(const DRAMSysConfiguration::Tr TrafficGeneratorHammer::TrafficGeneratorHammer(const sc_core::sc_module_name &name, const DRAMSysConfiguration::TraceHammer &conf, TraceSetup *setup) - : TrafficGeneratorIf(name, setup, 1, 1), generatorClk(evaluateGeneratorClk(conf)), rowIncrement(conf.rowIncrement), + : TrafficGeneratorIf(name, setup, 1, 1, false), generatorClk(evaluateGeneratorClk(conf)), rowIncrement(conf.rowIncrement), numRequests(conf.numRequests) { } diff --git a/DRAMSys/simulator/TrafficGenerator.h b/DRAMSys/simulator/TrafficGenerator.h index 16e957ea..10f6c66c 100644 --- a/DRAMSys/simulator/TrafficGenerator.h +++ b/DRAMSys/simulator/TrafficGenerator.h @@ -49,7 +49,7 @@ class TrafficGeneratorIf : public TrafficInitiator { public: TrafficGeneratorIf(const sc_core::sc_module_name &name, TraceSetup *setup, unsigned int maxPendingReadRequests, - unsigned int maxPendingWriteRequests); + unsigned int maxPendingWriteRequests, bool addLengthConverter); private: void sendNextPayload() override; @@ -76,6 +76,7 @@ public: private: static uint64_t evaluateSeed(const DRAMSysConfiguration::TraceGenerator &conf); static uint64_t evaluateMaxTransactions(const DRAMSysConfiguration::TraceGenerator &conf); + static bool evaluateAddLengthConverter(const DRAMSysConfiguration::TraceGenerator &conf); static uint64_t evaluateMinAddress(const DRAMSysConfiguration::TraceGeneratorTrafficState &state); static uint64_t evaluateMaxAddress(const DRAMSysConfiguration::TraceGeneratorTrafficState &state); static uint64_t evaluateAddressIncrement(const DRAMSysConfiguration::TraceGeneratorTrafficState &state); diff --git a/DRAMSys/simulator/TrafficInitiator.cpp b/DRAMSys/simulator/TrafficInitiator.cpp index 8783fcc9..83449c46 100644 --- a/DRAMSys/simulator/TrafficInitiator.cpp +++ b/DRAMSys/simulator/TrafficInitiator.cpp @@ -44,18 +44,18 @@ using namespace sc_core; using namespace tlm; TrafficInitiator::TrafficInitiator(const sc_module_name &name, TraceSetup *setup, - unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests) : - sc_module(name), payloadEventQueue(this, &TrafficInitiator::peqCallback), + unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, bool addLengthConverter) : + sc_module(name), + addLengthConverter(addLengthConverter), + payloadEventQueue(this, &TrafficInitiator::peqCallback), setup(setup), - maxPendingReadRequests(maxPendingReadRequests), maxPendingWriteRequests(maxPendingWriteRequests) + maxPendingReadRequests(maxPendingReadRequests), + maxPendingWriteRequests(maxPendingWriteRequests), + defaultDataLength(Configuration::getInstance().memSpec->defaultBytesPerBurst), + storageEnabled(Configuration::getInstance().storeMode != Configuration::StoreMode::NoStorage) { SC_THREAD(sendNextPayload); iSocket.register_nb_transport_bw(this, &TrafficInitiator::nb_transport_bw); - - if (Configuration::getInstance().storeMode == Configuration::StoreMode::NoStorage) - storageEnabled = false; - else - storageEnabled = true; } void TrafficInitiator::terminate() diff --git a/DRAMSys/simulator/TrafficInitiator.h b/DRAMSys/simulator/TrafficInitiator.h index 78c19e25..c727777d 100644 --- a/DRAMSys/simulator/TrafficInitiator.h +++ b/DRAMSys/simulator/TrafficInitiator.h @@ -57,9 +57,10 @@ class TrafficInitiator : public sc_core::sc_module public: tlm_utils::simple_initiator_socket iSocket; TrafficInitiator(const sc_core::sc_module_name &name, TraceSetup *setup, - unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests); + unsigned int maxPendingReadRequests, unsigned int maxPendingWriteRequests, bool addLengthConverter); SC_HAS_PROCESS(TrafficInitiator); virtual void sendNextPayload() = 0; + const bool addLengthConverter = false; protected: static sc_core::sc_time evaluateGeneratorClk(const DRAMSysConfiguration::TrafficInitiator &conf); @@ -68,7 +69,6 @@ protected: tlm_utils::peq_with_cb_and_phase payloadEventQueue; void terminate(); - bool storageEnabled = false; TraceSetup *setup; void sendToTarget(tlm::tlm_generic_payload &payload, const tlm::tlm_phase &phase, const sc_core::sc_time &delay); @@ -77,13 +77,14 @@ protected: uint64_t transactionsSent = 0; unsigned int pendingReadRequests = 0; unsigned int pendingWriteRequests = 0; - const unsigned int maxPendingReadRequests; - const unsigned int maxPendingWriteRequests; + + const unsigned int maxPendingReadRequests = 0; + const unsigned int maxPendingWriteRequests = 0; + bool payloadPostponed = false; bool finished = false; - - unsigned int burstLength; - unsigned int dataLength; + const unsigned int defaultDataLength = 64; + const bool storageEnabled = false; private: tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload &payload, tlm::tlm_phase &phase, diff --git a/DRAMSys/simulator/main.cpp b/DRAMSys/simulator/main.cpp index 9ce554a6..44962562 100644 --- a/DRAMSys/simulator/main.cpp +++ b/DRAMSys/simulator/main.cpp @@ -41,13 +41,16 @@ #include #include #include +#include #include #include +#include #include #include "simulation/DRAMSys.h" #include "TraceSetup.h" #include "TrafficInitiator.h" +#include "LengthConverter.h" #ifdef RECORDING #include "simulation/DRAMSysRecordable.h" @@ -96,41 +99,42 @@ int sc_main(int argc, char **argv) resources = argv[2]; } - std::vector players; + std::vector> players; + std::vector> lengthConverters; DRAMSysConfiguration::Configuration conf = DRAMSysConfiguration::from_path(simulationJson, resources); // Instantiate DRAMSys: - DRAMSys *dramSys; + std::unique_ptr dramSys; #ifdef RECORDING if (conf.simConfig.databaseRecording.isValid() && conf.simConfig.databaseRecording.getValue()) - dramSys = new DRAMSysRecordable("DRAMSys", conf); + dramSys = std::unique_ptr(new DRAMSysRecordable("DRAMSys", conf)); else #endif - dramSys = new DRAMSys("DRAMSys", conf); + dramSys = std::unique_ptr(new DRAMSys("DRAMSys", conf)); if (!conf.traceSetup.isValid()) SC_REPORT_FATAL("sc_main", "No tracesetup section provided."); // Instantiate STL Players: - TraceSetup *setup = new TraceSetup(conf.traceSetup.getValue(), resources, players); + TraceSetup setup(conf.traceSetup.getValue(), resources, players); // Bind STL Players with DRAMSys: - for (size_t i = 0; i < players.size(); i++) + for (auto& player : players) { - if (Configuration::getInstance().checkTLM2Protocol) + if (player->addLengthConverter) { - std::string str = "TLMCheckerPlayer" + std::to_string(i); - tlm_utils::tlm2_base_protocol_checker<> *playerTlmChecker = - new tlm_utils::tlm2_base_protocol_checker<>(str.c_str()); - dramSys->playersTlmCheckers.push_back(playerTlmChecker); - players[i]->iSocket.bind(dramSys->playersTlmCheckers[i]->target_socket); - dramSys->playersTlmCheckers[i]->initiator_socket.bind(dramSys->tSocket); + std::string converterName("Converter_"); + lengthConverters.emplace_back(new LengthConverter(converterName.append(player->name()).c_str(), + Configuration::getInstance().memSpec->maxBytesPerBurst, + Configuration::getInstance().storeMode != Configuration::StoreMode::NoStorage)); + player->iSocket.bind(lengthConverters.back()->tSocket); + lengthConverters.back()->iSocket.bind(dramSys->tSocket); } else { - players[i]->iSocket.bind(dramSys->tSocket); + player->iSocket.bind(dramSys->tSocket); } } @@ -150,11 +154,5 @@ int sc_main(int argc, char **argv) auto finish = std::chrono::high_resolution_clock::now(); std::chrono::duration elapsed = finish - start; std::cout << "Simulation took " + std::to_string(elapsed.count()) + " seconds." << std::endl; - - delete dramSys; - for (auto player : players) - delete player; - delete setup; - return 0; } diff --git a/DRAMSys/traceAnalyzer/CMakeLists.txt b/DRAMSys/traceAnalyzer/CMakeLists.txt index 31cf682c..5f4ea9bf 100644 --- a/DRAMSys/traceAnalyzer/CMakeLists.txt +++ b/DRAMSys/traceAnalyzer/CMakeLists.txt @@ -43,14 +43,22 @@ project(TraceAnalyzer) find_package(Python3 COMPONENTS Development) # Add QWT Dependency: -find_library(QWT_LIBRARY NAMES "qwt-qt5" "qwt" PATHS "$ENV{QWT_HOME}/lib") +find_library(QWT_LIBRARY NAMES "qwt-qt5" "qwt" PATHS + "$ENV{QWT_HOME}/lib" + "/opt/homebrew/opt/qwt-qt5/lib" +) find_path(QWT_INCLUDE_DIRS NAMES "qwt_plot.h" PATHS "/usr/include/qwt-qt5" "/usr/include/qwt" "$ENV{QWT_HOME}/include" + "/opt/homebrew/opt/qwt-qt5/include" + "/opt/homebrew/opt/qwt-qt5/lib/qwt.framework/Headers" ) # Add QT Library: +if (APPLE) + set(Qt5_DIR "/opt/homebrew/opt/qt@5/lib/cmake/Qt5") +endif(APPLE) find_package(Qt5 COMPONENTS Core Gui Widgets Sql REQUIRED) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp index 0c13f1fd..463fde5c 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.cpp @@ -69,7 +69,7 @@ void Phase::draw(QPainter *painter, const QwtScaleMap &xMap, if (!line->isCollapsed()) { drawPhaseSymbol(span.Begin(), span.End(), line->getYVal(), - drawingProperties.drawText, getPhaseSymbol(), painter, xMap, yMap); + drawingProperties.drawText, getPhaseSymbol(), painter, xMap, yMap, drawingProperties.textColor); if (getGranularity() == Granularity::Bankwise) { @@ -90,7 +90,7 @@ void Phase::draw(QPainter *painter, const QwtScaleMap &xMap, for (auto commandBusLine : drawingProperties.getCommandBusLines()) { drawPhaseSymbol(span.Begin(), span.End(), commandBusLine->getYVal(), - false, PhaseSymbol::Hexagon, painter, xMap, yMap); + false, PhaseSymbol::Hexagon, painter, xMap, yMap, drawingProperties.textColor); } } @@ -99,14 +99,14 @@ void Phase::draw(QPainter *painter, const QwtScaleMap &xMap, for (auto dataBusLine : drawingProperties.getDataBusLines()) { drawPhaseSymbol(spanOnDataBus->Begin(), spanOnDataBus->End(), dataBusLine->getYVal(), - false, PhaseSymbol::Hexagon, painter, xMap, yMap); + false, PhaseSymbol::Hexagon, painter, xMap, yMap, drawingProperties.textColor); } } } void Phase::drawPhaseSymbol(traceTime begin, traceTime end, double y, bool drawtext, PhaseSymbol symbol, QPainter *painter, const QwtScaleMap &xMap, - const QwtScaleMap &yMap) const + const QwtScaleMap &yMap, QColor textColor) const { double yVal = yMap.transform(y); double symbolHeight = yMap.transform(0) - yMap.transform(hexagonHeight); @@ -126,7 +126,7 @@ void Phase::drawPhaseSymbol(traceTime begin, traceTime end, double y, if (drawtext) drawText(painter, Name(), QPoint(static_cast(xMap.transform(begin)), - static_cast(yVal + symbolHeight / 2)), TextPositioning::bottomRight); + static_cast(yVal + symbolHeight / 2)), TextPositioning::bottomRight, textColor); } void Phase::drawPhaseDependencies(traceTime begin, traceTime end, double y, diff --git a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h index 3f05b8d2..ce474fe8 100644 --- a/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h +++ b/DRAMSys/traceAnalyzer/businessObjects/phases/phase.h @@ -99,7 +99,7 @@ protected: virtual QColor getPhaseColor() const = 0; virtual void drawPhaseSymbol(traceTime begin, traceTime end, double y, bool drawtext, PhaseSymbol symbol, QPainter *painter, const QwtScaleMap &xMap, - const QwtScaleMap &yMap) const; + const QwtScaleMap &yMap, QColor textColor) const; virtual void drawPhaseDependencies(traceTime begin, traceTime end, double y, const TraceDrawingProperties &drawingProperties, QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap) const; diff --git a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h index 6c437ad0..119d1a24 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h +++ b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.h @@ -92,6 +92,7 @@ public: bool drawBorder; DependencyOptions drawDependenciesOption; ColorGrouping colorGrouping; + QColor textColor; unsigned int numberOfRanks = 1; unsigned int numberOfBankGroups = 1; diff --git a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp index 7c986afd..d81bc852 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp +++ b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp @@ -302,6 +302,7 @@ void TracePlot::setUpDrawingProperties() { drawingProperties.init(navigator->getTracePlotLines(), navigator->getTracePlotLineCache(), this); + drawingProperties.textColor = palette().text().color(); drawingProperties.numberOfRanks = navigator->GeneralTraceInfo().numberOfRanks; drawingProperties.numberOfBankGroups = navigator->GeneralTraceInfo().numberOfBankGroups; drawingProperties.numberOfBanks = navigator->GeneralTraceInfo().numberOfBanks; diff --git a/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp b/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp index 79d75c72..883c7c5c 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp @@ -106,6 +106,7 @@ void TraceScroller::setUpDrawingProperties() { drawingProperties.init(navigator->getTracePlotLines(), navigator->getTracePlotLineCache()); + drawingProperties.textColor = palette().text().color(); drawingProperties.numberOfRanks = navigator->GeneralTraceInfo().numberOfRanks; drawingProperties.numberOfBankGroups = navigator->GeneralTraceInfo().numberOfBankGroups; drawingProperties.numberOfBanks = navigator->GeneralTraceInfo().numberOfBanks; diff --git a/DRAMSys/traceAnalyzer/selectmetrics.ui b/DRAMSys/traceAnalyzer/selectmetrics.ui index b74e0ca8..cfbf9f22 100644 --- a/DRAMSys/traceAnalyzer/selectmetrics.ui +++ b/DRAMSys/traceAnalyzer/selectmetrics.ui @@ -67,9 +67,6 @@ true - - - true @@ -78,13 +75,10 @@ 0 0 - 469 - 599 + 467 + 597 - - background-color:white - diff --git a/README.md b/README.md index 4deed4ee..d5d1491c 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,8 @@ The JSON code below shows an example configuration: "tracesetup": [ { "clkMhz": 300, - "name": "ddr3_example.stl" + "name": "ddr3_example.stl", + "addLengthConverter": true }, { "clkMhz": 2000, @@ -160,6 +161,7 @@ Fields Description: Each **trace setup** device configuration can be a **trace player** ("type": "player"), a **traffic generator** ("type": "generator") or a **row hammer generator** ("type": "hammer"). By not specifing the **type** parameter, the device will act as a **trace player**. All device configurations must define a **clkMhz** (operation frequency of the **traffic initiator**) and a **name** (in case of a trace player this specifies the **trace file** to play; in case of a generator this field is only for identification purposes). +The optional parameter **addLengthConverter** adds a transaction length converter between initiator and DRAMSys. This unit divides a large transaction up into several smaller transactions with the maximum length of one DRAM burst access. The **maxPendingReadRequests** and **maxPendingWriteRequests** parameters define the maximum number of outstanding read/write requests. The current implementation delays all memory accesses when one limit is reached. The default value (0) disables the limit. A **traffic generator** can be configured to generate **numRequests** requests in total, of which the **rwRatio** field defines the probability of one request being a read request. The **seed** parameter can be used to produce identical results for all simulations. **minAddress** and **maxAddress** specify the address range, by default the whole address range is used. The parameter **addressDistribution** can either be set to **"random"** or **"sequential"**. In case of **"sequential"** the additional **addressIncrement** field must be specified, defining the address increment after each request. @@ -171,7 +173,7 @@ Most configuration fields reference other JSON files which contain more speciali #### Trace Files -A **trace file** is a prerecorded file containing memory transactions. Each memory transaction has a time stamp that tells the simulator when it shall happen, a transaction type (*read* or *write*) and a hexadecimal memory address. +A **trace file** is a prerecorded file containing memory transactions. Each memory transaction has a time stamp that tells the simulator when it shall happen, a transaction type (*read* or *write*) and a hexadecimal memory address. The optional length parameter (in bytes) allows sending transactions with a custom length that does not match the length of a single DRAM burst access. In this case a length converter has to be added. Write transactions also have to specify a data field when storage is enabled in DRAMSys. There are two different kinds of trace files. They differ in their timing behavior and are distinguished by their file extension. @@ -183,11 +185,11 @@ Syntax example: ``` # Comment lines begin with # -# [clock-cyle]: [write|read] [hex-address] [hex-data (optional)] -31: read 0x400140 -33: read 0x400160 -56: write 0x7fff8000 0x123456789abcdef... -81: read 0x400180 +# cycle: [(length)] command hex-address [hex-data] +31: read 0x400140 +33: read 0x400160 +56: write 0x7fff8000 0x123456789abcdef... +81: (128) read 0x400180 ``` ##### Relative STL Traces (.rstl) @@ -198,11 +200,11 @@ Syntax example: ``` # Comment lines begin with # -# [clock-cyle]: [write|read] [hex-address] [hex-data (optional)] -31: read 0x400140 -2: read 0x400160 -23: write 0x7fff8000 0x123456789abcdef... -25: read 0x400180 +# cycle: [(length)] command hex-address [hex-data] +31: read 0x400140 +2: (512) read 0x400160 +23: write 0x7fff8000 0x123456789abcdef... +10: read 0x400180 ``` ##### Elastic Traces diff --git a/utils/install_mac.sh b/utils/install_mac.sh new file mode 100755 index 00000000..5e59e0e5 --- /dev/null +++ b/utils/install_mac.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Copyright (c) 2018, University of Kaiserslautern +# 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. +# +# Author: Matthias Jung + +brew install qt@5 qwt-qt5 + +echo -e "Done."