diff --git a/DRAMSys/library/CMakeLists.txt b/DRAMSys/library/CMakeLists.txt index d5e48ecf..6cfdb33f 100644 --- a/DRAMSys/library/CMakeLists.txt +++ b/DRAMSys/library/CMakeLists.txt @@ -78,7 +78,6 @@ if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src/common/third_party/sqlite-amalgamation) endif() add_library(DRAMSysLibrary - src/common/AddressDecoder.cpp src/common/DebugManager.cpp src/common/dramExtensions.cpp src/common/tlm2_base_protocol_checker.h @@ -138,6 +137,10 @@ add_library(DRAMSysLibrary src/controller/scheduler/SchedulerFifo.cpp src/controller/scheduler/SchedulerFrFcfs.cpp src/controller/scheduler/SchedulerFrFcfsGrp.cpp + + src/controller/scheduler/BufferIF.h + src/controller/scheduler/BufferBankwise.cpp + src/controller/scheduler/BufferReadWrite.cpp src/error/eccbaseclass.cpp src/error/ecchamming.cpp @@ -148,6 +151,7 @@ add_library(DRAMSysLibrary src/error/ECC/Word.cpp src/simulation/Arbiter.cpp + src/simulation/AddressDecoder.cpp src/simulation/DRAMSys.cpp src/simulation/ReorderBuffer.h src/simulation/TemperatureController.cpp diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index 5d1e1aa0..ec743d4b 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -82,23 +82,88 @@ void Configuration::setParameter(std::string name, nlohmann::json value) { // MCConfig if (name == "PagePolicy") - pagePolicy = value; + { + if (value == "Open") + pagePolicy = PagePolicy::Open; + else if (value == "Closed") + pagePolicy = PagePolicy::Closed; + else if (value == "OpenAdaptive") + pagePolicy = PagePolicy::OpenAdaptive; + else if (value == "ClosedAdaptive") + pagePolicy = PagePolicy::ClosedAdaptive; + else + SC_REPORT_FATAL("Configuration", "Unsupported page policy!"); + } else if (name == "Scheduler") - scheduler = value; + { + if (value == "Fifo") + scheduler = Scheduler::Fifo; + else if (value == "FrFcfs") + scheduler = Scheduler::FrFcfs; + else if (value == "FrFcfsGrp") + scheduler = Scheduler::FrFcfsGrp; + else + SC_REPORT_FATAL("Configuration", "Unsupported scheduler!"); + } + else if (name == "SchedulerBuffer") + { + if (value == "Bankwise") + schedulerBuffer = SchedulerBuffer::Bankwise; + else if (value == "ReadWrite") + schedulerBuffer = SchedulerBuffer::ReadWrite; + else + SC_REPORT_FATAL("Configuration", "Unsupported scheduler buffer!"); + } else if (name == "RequestBufferSize") + { requestBufferSize = value; + if (requestBufferSize == 0) + SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!"); + } else if (name == "CmdMux") - cmdMux = value; + { + if (value == "Oldest") + cmdMux = CmdMux::Oldest; + else if (value == "Strict") + cmdMux = CmdMux::Strict; + else + SC_REPORT_FATAL("Configuration", "Unsupported cmd mux!"); + } else if (name == "RespQueue") - respQueue = value; + { + if (value == "Fifo") + respQueue = RespQueue::Fifo; + else if (value == "Reorder") + respQueue = RespQueue::Reorder; + else + SC_REPORT_FATAL("Configuration", "Unsupported response queue!"); + } else if (name == "RefreshPolicy") - refreshPolicy = value; + { + if (value == "NoRefresh") + refreshPolicy = RefreshPolicy::NoRefresh; + else if (value == "Rankwise") + refreshPolicy = RefreshPolicy::Rankwise; + else if (value == "Bankwise") + refreshPolicy = RefreshPolicy::Bankwise; + else if (value == "Groupwise") + refreshPolicy = RefreshPolicy::Groupwise; + else + SC_REPORT_FATAL("Configuration", "Unsupported refresh policy!"); + } else if (name == "RefreshMaxPostponed") refreshMaxPostponed = value; else if (name == "RefreshMaxPulledin") refreshMaxPulledin = value; else if (name == "PowerDownPolicy") - powerDownPolicy = value; + { + if (value == "NoPowerDown") + powerDownPolicy = PowerDownPolicy::NoPowerDown; + else if (value == "Staggered") + powerDownPolicy = PowerDownPolicy::Staggered; + else + SC_REPORT_FATAL("Configuration", "Unsupported power down policy!"); + } else if (name == "PowerDownTimeout") powerDownTimeout = value; //SimConfig------------------------------------------------ @@ -114,9 +179,7 @@ void Configuration::setParameter(std::string name, nlohmann::json value) { windowSize = value; if (windowSize == 0) - SC_REPORT_FATAL("Configuration", - ("Invalid value for parameter " + name + - ". This parameter must be at least one.").c_str()); + SC_REPORT_FATAL("Configuration", "Minimum window size is 1"); } else if (name == "Debug") debug = value; @@ -125,26 +188,37 @@ void Configuration::setParameter(std::string name, nlohmann::json value) else if (name == "SimulationProgressBar") simulationProgressBar = value; else if (name == "AddressOffset") - { -#ifdef DRAMSYS_GEM5 addressOffset = value; -#else - addressOffset = 0; -#endif - } else if (name == "UseMalloc") useMalloc = value; else if (name == "CheckTLM2Protocol") checkTLM2Protocol = value; else if (name == "ECCControllerMode") - ECCMode = value; + { + if (value == "Disabled") + eccMode = ECCMode::Disabled; + else if (value == "Hamming") + eccMode = ECCMode::Hamming; + else + SC_REPORT_FATAL("Configuration", "Unsupported ECC mode!"); + } // Specification for ErrorChipSeed, ErrorCSVFile path and StoreMode else if (name == "ErrorChipSeed") errorChipSeed = value; else if (name == "ErrorCSVFile") errorCSVFile = value; else if (name == "StoreMode") - storeMode = value; + { + if (value == "NoStorage") + storeMode = StoreMode::NoStorage; + else if (value == "Store") + storeMode = StoreMode::Store; + else if (value == "ErrorModel") + storeMode = StoreMode::ErrorModel; + else + SC_REPORT_FATAL("Configuration", "Unsupported store mode!"); + } + // Temperature Simulation related else if (name == "TemperatureScale") { @@ -187,75 +261,17 @@ void Configuration::setPathToResources(std::string path) temperatureSim.setPathToResources(path); } -// Returns the total memory size in bytes -std::uint64_t Configuration::getSimMemSizeInBytes() -{ - // 1. Get number of banks, rows, columns and data width in bits for one die (or chip) - std::string type = memSpec->memoryType; - std::uint64_t ranks = memSpec->numberOfRanks; - std::uint64_t bankgroups = memSpec->numberOfBankGroups; - std::uint64_t banks = memSpec->numberOfBanks; - std::uint64_t rows = memSpec->numberOfRows; - std::uint64_t columns = memSpec->numberOfColumns; - std::uint64_t bitWidth = memSpec->bitWidth; - std::uint64_t devicesOnDIMM = memSpec->numberOfDevicesOnDIMM; - // 2. Calculate size of one DRAM chip in bits - std::uint64_t chipBitSize = banks * rows * columns * bitWidth; - // 3. Calculate size of one DRAM chip in bytes - std::uint64_t chipSize = chipBitSize / 8; - // 4. Total memory size in Bytes of one DIMM (with only support of 1 rank on a DIMM) - std::uint64_t memorySize = chipSize * memSpec->numberOfDevicesOnDIMM; - - std::cout << headline << std::endl; - std::cout << "Per Channel Configuration:" << std::endl << std::endl; - std::cout << " Memory type: " << type << std::endl; - std::cout << " Memory size in bytes: " << memorySize << std::endl; - std::cout << " Number of ranks: " << ranks << std::endl; - std::cout << " Number of bankgroups: " << bankgroups << std::endl; - std::cout << " Number of banks: " << banks << std::endl; - std::cout << " Number of rows: " << rows << std::endl; - std::cout << " Number of columns: " << columns << std::endl; - std::cout << " Chip data bus width: " << bitWidth << std::endl; - std::cout << " Chip size in bits: " << chipBitSize << std::endl; - std::cout << " Chip Size in bytes: " << chipSize << std::endl; - std::cout << " Devices/Chips on DIMM: " << devicesOnDIMM << std::endl; - std::cout << std::endl; - - assert(memorySize > 0); - return memorySize; -} - -// Returns the width of the data bus. -// All DRAM chips on a DIMM operate in lockstep, -// which constituing aggregate data bus width = chip's bus width * # locksteep-operated chips -// The bus width is given in bits, e.g., 64-bit data bus, 128-bit data bus, etc. -unsigned int Configuration::getDataBusWidth() -{ - return memSpec->bitWidth * memSpec->numberOfDevicesOnDIMM; -} - -// Returns the number of bytes transfered in a burst -unsigned int Configuration::getBytesPerBurst() -{ - return (memSpec->burstLength * getDataBusWidth()) / 8; -} - // 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) { // Manipulate the number of bytes only if there is an ECC Controller selected - if (ECCMode == "Disabled") + if (eccMode == ECCMode::Disabled) return nBytes; - else if (ECCMode == "Hamming") + else // if (eccMode == ECCMode::Hamming) { assert(pECC != nullptr); return pECC->AllocationSize(nBytes); } - else - { - SC_REPORT_FATAL("Configuration", ("ECC mode " + ECCMode + " unsupported").c_str()); - return 0; - } } void Configuration::loadSimConfig(Configuration &config, std::string simconfigUri) diff --git a/DRAMSys/library/src/configuration/Configuration.h b/DRAMSys/library/src/configuration/Configuration.h index 75176ae5..bd8a56b3 100644 --- a/DRAMSys/library/src/configuration/Configuration.h +++ b/DRAMSys/library/src/configuration/Configuration.h @@ -69,15 +69,16 @@ public: std::string pathToResources; // MCConfig: - std::string pagePolicy = "Open"; - std::string scheduler = "Fifo"; - std::string cmdMux = "Oldest"; - std::string respQueue = "Fifo"; + enum class PagePolicy {Open, Closed, OpenAdaptive, ClosedAdaptive} pagePolicy; + enum class Scheduler {Fifo, FrFcfs, FrFcfsGrp} scheduler; + enum class SchedulerBuffer {Bankwise, ReadWrite} schedulerBuffer; + enum class CmdMux {Oldest, Strict} cmdMux; + enum class RespQueue {Fifo, Reorder} respQueue; unsigned int requestBufferSize = 8; - std::string refreshPolicy = "Rankwise"; + enum class RefreshPolicy {NoRefresh, Rankwise, Bankwise, Groupwise} refreshPolicy; unsigned int refreshMaxPostponed = 0; unsigned int refreshMaxPulledin = 0; - std::string powerDownPolicy = "NoPowerDown"; + enum class PowerDownPolicy {NoPowerDown, Staggered} powerDownPolicy; unsigned int powerDownTimeout = 3; // SimConfig @@ -90,7 +91,7 @@ public: bool thermalSimulation = false; bool simulationProgressBar = false; bool checkTLM2Protocol = false; - std::string ECCMode = "Disabled"; + enum class ECCMode {Disabled, Hamming} eccMode; ECCBaseClass *pECC = nullptr; bool gem5 = false; bool useMalloc = false; @@ -104,14 +105,11 @@ public: //Configs for Seed, csv file and StorageMode unsigned int errorChipSeed; std::string errorCSVFile = "not defined."; - std::string storeMode; + enum class StoreMode {NoStorage, Store, ErrorModel} storeMode; // Temperature Simulation related TemperatureSimConfig temperatureSim; - std::uint64_t getSimMemSizeInBytes(); - unsigned int getDataBusWidth(); - unsigned int getBytesPerBurst(); unsigned int adjustNumBytesAfterECC(unsigned bytes); void setPathToResources(std::string path); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp index ac893709..c3a73127 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.cpp @@ -43,7 +43,8 @@ using namespace tlm; using json = nlohmann::json; -MemSpec::MemSpec(json &memspec, unsigned numberOfChannels, +MemSpec::MemSpec(json &memspec, MemoryType memoryType, + unsigned numberOfChannels, unsigned numberOfRanks, unsigned banksPerRank, unsigned groupsPerRank, unsigned banksPerGroup, unsigned numberOfBanks, unsigned numberOfBankGroups, @@ -61,10 +62,12 @@ MemSpec::MemSpec(json &memspec, unsigned numberOfChannels, burstLength(parseUint(memspec["memarchitecturespec"]["burstLength"],"burstLength")), dataRate(parseUint(memspec["memarchitecturespec"]["dataRate"],"dataRate")), bitWidth(parseUint(memspec["memarchitecturespec"]["width"],"width")), + dataBusWidth(bitWidth * numberOfDevicesOnDIMM), + bytesPerBurst((burstLength * dataBusWidth) / 8), fCKMHz(parseUdouble(memspec["memtimingspec"]["clkMhz"], "clkMhz")), tCK(sc_time(1.0 / fCKMHz, SC_US)), memoryId(parseString(memspec["memoryId"], "memoryId")), - memoryType(parseString(memspec["memoryType"], "memoryType")), + memoryType(memoryType), burstDuration(tCK * (burstLength / dataRate)) { commandLengthInCycles = std::vector(numberOfCommands(), 1); diff --git a/DRAMSys/library/src/configuration/memspec/MemSpec.h b/DRAMSys/library/src/configuration/memspec/MemSpec.h index 1f9687ab..5aa935f9 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpec.h @@ -61,13 +61,15 @@ public: const unsigned burstLength; const unsigned dataRate; const unsigned bitWidth; + const unsigned dataBusWidth; + const unsigned bytesPerBurst; // Clock const double fCKMHz; const sc_time tCK; - std::string memoryId; - std::string memoryType; + const std::string memoryId; + const enum class MemoryType {DDR3, DDR4, DDR5, LPDDR4, WideIO, WideIO2, GDDR5, GDDR5X, GDDR6, HBM2} memoryType; virtual ~MemSpec() {} @@ -79,9 +81,11 @@ public: virtual TimeInterval getIntervalOnDataStrobe(Command) const = 0; sc_time getCommandLength(Command) const; + virtual uint64_t getSimMemSizeInBytes() const = 0; protected: - MemSpec(nlohmann::json &memspec, unsigned numberOfChannels, + MemSpec(nlohmann::json &memspec, MemoryType memoryType, + unsigned numberOfChannels, unsigned numberOfRanks, unsigned banksPerRank, unsigned groupsPerRank, unsigned banksPerGroup, unsigned numberOfBanks, unsigned numberOfBankGroups, diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp index 21a1434a..7cc92848 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecDDR3::MemSpecDDR3(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::DDR3, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), @@ -132,3 +132,27 @@ TimeInterval MemSpecDDR3::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecDDR3::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfDevicesOnDIMM * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "DDR3" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << " Devices on DIMM: " << numberOfDevicesOnDIMM << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h index f71cde71..6c9174de 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR3.h @@ -91,6 +91,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECDDR3_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp index cd9c2624..23f6773e 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.cpp @@ -40,7 +40,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecDDR4::MemSpecDDR4(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::DDR4, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), @@ -151,3 +151,28 @@ TimeInterval MemSpecDDR4::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecDDR4::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfDevicesOnDIMM * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "DDR4" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Bank groups per rank: " << groupsPerRank << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << " Devices on DIMM: " << numberOfDevicesOnDIMM << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h index d6da746e..c63fb36f 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR4.h @@ -99,6 +99,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECDDR4_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp index 9a4892cf..bd5e92ef 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.cpp @@ -40,7 +40,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecDDR5::MemSpecDDR5(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::DDR5, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), @@ -194,3 +194,31 @@ TimeInterval MemSpecDDR5::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecDDR5::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfDevicesOnDIMM * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration: " << std::endl << std::endl; + std::cout << " Memory type: " << "DDR5" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " DIMMs: " << numberOfDIMMRanks << std::endl; + std::cout << " Physical Ranks per DIMM: " << physicalRanksPerDIMMRank << std::endl; + std::cout << " Logical Ranks per device: " << logicalRanksPerPhysicalRank << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Bank groups per rank: " << groupsPerRank << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << " Devices on DIMM: " << numberOfDevicesOnDIMM << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h index 187fe07d..13883326 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecDDR5.h @@ -110,6 +110,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECDDR5_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp index 3ca42b65..f99ce411 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecGDDR5::MemSpecGDDR5(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::GDDR5, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), @@ -142,3 +142,27 @@ TimeInterval MemSpecGDDR5::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecGDDR5::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "GDDR5" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Bank groups per rank: " << groupsPerRank << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h index 690f29b5..3abeb869 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5.h @@ -90,6 +90,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECGDDR5_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp index e2fd9855..84f581fa 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecGDDR5X::MemSpecGDDR5X(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::GDDR5X, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), @@ -142,3 +142,27 @@ TimeInterval MemSpecGDDR5X::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecGDDR5X::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "GDDR5X" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Bank groups per rank: " << groupsPerRank << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h index 130606f7..10fcd5b5 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR5X.h @@ -90,6 +90,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECGDDR5X_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp index a1b6e4e3..4cde4e10 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecGDDR6::MemSpecGDDR6(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::GDDR6, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), @@ -144,3 +144,27 @@ TimeInterval MemSpecGDDR6::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecGDDR6::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "GDDR6" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Bank groups per rank: " << groupsPerRank << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h index 7e2f91c8..c0f9f7d1 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecGDDR6.h @@ -92,6 +92,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECGDDR6_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp index 784b4f99..3f61973b 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecHBM2::MemSpecHBM2(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::HBM2, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), @@ -139,3 +139,27 @@ TimeInterval MemSpecHBM2::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecHBM2::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "HBM2" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Bank groups per rank: " << groupsPerRank << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h index 148be20a..618f40db 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecHBM2.h @@ -85,6 +85,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECHBM2_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp index 915c14c4..ca0a2fc1 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecLPDDR4::MemSpecLPDDR4(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::LPDDR4, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), @@ -147,3 +147,26 @@ TimeInterval MemSpecLPDDR4::getIntervalOnDataStrobe(Command command) const } } +uint64_t MemSpecLPDDR4::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "GDDR5" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} + diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h index d85998a9..4c7d0d52 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecLPDDR4.h @@ -85,6 +85,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECLPDDR4_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp index 577c1ca3..f0df06df 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecWideIO::MemSpecWideIO(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::WideIO, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), @@ -140,3 +140,26 @@ TimeInterval MemSpecWideIO::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecWideIO::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "GDDR5" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h index 49d351f7..eb1ad7d7 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO.h @@ -97,6 +97,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECWIDEIO_H diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp index b74129ba..97006423 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.cpp @@ -39,7 +39,7 @@ using namespace tlm; using json = nlohmann::json; MemSpecWideIO2::MemSpecWideIO2(json &memspec) - : MemSpec(memspec, + : MemSpec(memspec, MemoryType::WideIO2, parseUint(memspec["memarchitecturespec"]["nbrOfChannels"],"nbrOfChannels"), parseUint(memspec["memarchitecturespec"]["nbrOfRanks"],"nbrOfRanks"), parseUint(memspec["memarchitecturespec"]["nbrOfBanks"],"nbrOfBanks"), @@ -69,9 +69,9 @@ MemSpecWideIO2::MemSpecWideIO2(json &memspec) tWTR (tCK * parseUint(memspec["memtimingspec"]["WTR"], "WTR")), tRRD (tCK * parseUint(memspec["memtimingspec"]["RRD"], "RRD")), tFAW (tCK * parseUint(memspec["memtimingspec"]["FAW"], "FAW")), - tREFI (tCK * (unsigned)(parseUint(memspec["memtimingspec"]["REFI"], "REFI") + tREFI (tCK * static_cast(parseUint(memspec["memtimingspec"]["REFI"], "REFI") * parseUdouble(memspec["memtimingspec"]["REFM"], "REFM"))), - tREFIpb (tCK * (unsigned)(parseUint(memspec["memtimingspec"]["REFIPB"], "REFIPB") + tREFIpb (tCK * static_cast(parseUint(memspec["memtimingspec"]["REFIPB"], "REFIPB") * parseUdouble(memspec["memtimingspec"]["REFM"], "REFM"))), tRFCab (tCK * parseUint(memspec["memtimingspec"]["RFCAB"], "RFCAB")), tRFCpb (tCK * parseUint(memspec["memtimingspec"]["RFCPB"], "RFCPB")), @@ -131,3 +131,26 @@ TimeInterval MemSpecWideIO2::getIntervalOnDataStrobe(Command command) const return TimeInterval(); } } + +uint64_t MemSpecWideIO2::getSimMemSizeInBytes() const +{ + uint64_t deviceSizeBits = static_cast(banksPerRank) * numberOfRows * numberOfColumns * bitWidth; + uint64_t deviceSizeBytes = deviceSizeBits / 8; + uint64_t memorySizeBytes = deviceSizeBytes * numberOfRanks; + + std::cout << headline << std::endl; + std::cout << "Per Channel Configuration:" << std::endl << std::endl; + std::cout << " Memory type: " << "GDDR5" << std::endl; + std::cout << " Memory size in bytes: " << memorySizeBytes << std::endl; + std::cout << " Ranks: " << numberOfRanks << std::endl; + std::cout << " Banks per rank: " << banksPerRank << std::endl; + std::cout << " Rows per bank: " << numberOfRows << std::endl; + std::cout << " Columns per row: " << numberOfColumns << std::endl; + std::cout << " Device width in bits: " << bitWidth << std::endl; + std::cout << " Device size in bits: " << deviceSizeBits << std::endl; + std::cout << " Device size in bytes: " << deviceSizeBytes << std::endl; + std::cout << std::endl; + + assert(memorySizeBytes > 0); + return memorySizeBytes; +} diff --git a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h index 877f15bd..35503a61 100644 --- a/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h +++ b/DRAMSys/library/src/configuration/memspec/MemSpecWideIO2.h @@ -79,6 +79,8 @@ public: virtual sc_time getExecutionTime(Command, const tlm::tlm_generic_payload &) const override; virtual TimeInterval getIntervalOnDataStrobe(Command) const override; + + virtual uint64_t getSimMemSizeInBytes() const override; }; #endif // MEMSPECWIDEIO2_H diff --git a/DRAMSys/library/src/controller/Controller.cpp b/DRAMSys/library/src/controller/Controller.cpp index 3417ca2b..9cbb2715 100644 --- a/DRAMSys/library/src/controller/Controller.cpp +++ b/DRAMSys/library/src/controller/Controller.cpp @@ -77,76 +77,66 @@ Controller::Controller(sc_module_name name) : readyCommands.reserve(memSpec->numberOfBanks); // instantiate timing checker - if (memSpec->memoryType == "DDR3") + if (memSpec->memoryType == MemSpec::MemoryType::DDR3) checker = new CheckerDDR3(); - else if (memSpec->memoryType == "DDR4") + else if (memSpec->memoryType == MemSpec::MemoryType::DDR4) checker = new CheckerDDR4(); - else if (memSpec->memoryType == "DDR5") + else if (memSpec->memoryType == MemSpec::MemoryType::DDR5) checker = new CheckerDDR5(); - else if (memSpec->memoryType == "WIDEIO_SDR") + else if (memSpec->memoryType == MemSpec::MemoryType::WideIO) checker = new CheckerWideIO(); - else if (memSpec->memoryType == "LPDDR4") + else if (memSpec->memoryType == MemSpec::MemoryType::LPDDR4) checker = new CheckerLPDDR4(); - else if (memSpec->memoryType == "WIDEIO2") + else if (memSpec->memoryType == MemSpec::MemoryType::WideIO2) checker = new CheckerWideIO2(); - else if (memSpec->memoryType == "HBM2") + else if (memSpec->memoryType == MemSpec::MemoryType::HBM2) checker = new CheckerHBM2(); - else if (memSpec->memoryType == "GDDR5") + else if (memSpec->memoryType == MemSpec::MemoryType::GDDR5) checker = new CheckerGDDR5(); - else if (memSpec->memoryType == "GDDR5X") + else if (memSpec->memoryType == MemSpec::MemoryType::GDDR5X) checker = new CheckerGDDR5X(); - else if (memSpec->memoryType == "GDDR6") + else if (memSpec->memoryType == MemSpec::MemoryType::GDDR6) checker = new CheckerGDDR6(); - else - SC_REPORT_FATAL("Controller", "Unsupported DRAM type!"); // instantiate scheduler and command mux - if (config.scheduler == "Fifo") + if (config.scheduler == Configuration::Scheduler::Fifo) scheduler = new SchedulerFifo(); - else if (config.scheduler == "FrFcfs") + else if (config.scheduler == Configuration::Scheduler::FrFcfs) scheduler = new SchedulerFrFcfs(); - else if (config.scheduler == "FrFcfsGrp") + else if (config.scheduler == Configuration::Scheduler::FrFcfsGrp) scheduler = new SchedulerFrFcfsGrp(); - else - SC_REPORT_FATAL("Controller", "Selected scheduler not supported!"); - if (config.cmdMux == "Oldest") + if (config.cmdMux == Configuration::CmdMux::Oldest) cmdMux = new CmdMuxOldest(); - else if (config.cmdMux == "Strict") + else if (config.cmdMux == Configuration::CmdMux::Strict) cmdMux = new CmdMuxStrict(); - else - SC_REPORT_FATAL("Controller", "Selected cmdmux not supported!"); - if (config.respQueue == "Fifo") + if (config.respQueue == Configuration::RespQueue::Fifo) respQueue = new RespQueueFifo(); - else if (config.respQueue == "Reorder") + else if (config.respQueue == Configuration::RespQueue::Reorder) respQueue = new RespQueueReorder(); - else - SC_REPORT_FATAL("Controller", "Selected respqueue not supported!"); // instantiate bank machines (one per bank) - if (config.pagePolicy == "Open") + if (config.pagePolicy == Configuration::PagePolicy::Open) { for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++) bankMachines.push_back(new BankMachineOpen(scheduler, checker, Bank(bankID))); } - else if (config.pagePolicy == "OpenAdaptive") + else if (config.pagePolicy == Configuration::PagePolicy::OpenAdaptive) { for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++) bankMachines.push_back(new BankMachineOpenAdaptive(scheduler, checker, Bank(bankID))); } - else if (config.pagePolicy == "Closed") + else if (config.pagePolicy == Configuration::PagePolicy::Closed) { for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++) bankMachines.push_back(new BankMachineClosed(scheduler, checker, Bank(bankID))); } - else if (config.pagePolicy == "ClosedAdaptive") + else if (config.pagePolicy == Configuration::PagePolicy::ClosedAdaptive) { for (unsigned bankID = 0; bankID < memSpec->numberOfBanks; bankID++) bankMachines.push_back(new BankMachineClosedAdaptive(scheduler, checker, Bank(bankID))); } - else - SC_REPORT_FATAL("Controller", "Selected page policy not supported!"); for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { @@ -155,7 +145,7 @@ Controller::Controller(sc_module_name name) : } // instantiate power-down managers (one per rank) - if (config.powerDownPolicy == "NoPowerDown") + if (config.powerDownPolicy == Configuration::PowerDownPolicy::NoPowerDown) { for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { @@ -163,7 +153,7 @@ Controller::Controller(sc_module_name name) : powerDownManagers.push_back(manager); } } - else if (config.powerDownPolicy == "Staggered") + else if (config.powerDownPolicy == Configuration::PowerDownPolicy::Staggered) { for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { @@ -171,16 +161,14 @@ Controller::Controller(sc_module_name name) : powerDownManagers.push_back(manager); } } - else - SC_REPORT_FATAL("Controller", "Selected power-down mode not supported!"); // instantiate refresh managers (one per rank) - if (config.refreshPolicy == "NoRefresh") + if (config.refreshPolicy == Configuration::RefreshPolicy::NoRefresh) { for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) refreshManagers.push_back(new RefreshManagerDummy()); } - else if (config.refreshPolicy == "Rankwise") + else if (config.refreshPolicy == Configuration::RefreshPolicy::Rankwise) { for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { @@ -189,7 +177,7 @@ Controller::Controller(sc_module_name name) : refreshManagers.push_back(manager); } } - else if (config.refreshPolicy == "Groupwise") + else if (config.refreshPolicy == Configuration::RefreshPolicy::Groupwise) { for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { @@ -198,7 +186,7 @@ Controller::Controller(sc_module_name name) : refreshManagers.push_back(manager); } } - else if (config.refreshPolicy == "Bankwise") + else if (config.refreshPolicy == Configuration::RefreshPolicy::Bankwise) { for (unsigned rankID = 0; rankID < memSpec->numberOfRanks; rankID++) { diff --git a/DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp b/DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp new file mode 100644 index 00000000..d73a3a58 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferBankwise.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#include "BufferBankwise.h" +#include "../../common/dramExtensions.h" + +BufferBankwise::BufferBankwise(unsigned requestBufferSize, unsigned numberOfBanks) + : requestBufferSize(requestBufferSize) +{ + requestsOnBank = std::vector(numberOfBanks, 0); +} + +bool BufferBankwise::hasBufferSpace() const +{ + return (requestsOnBank[lastBankID] < requestBufferSize); +} + +void BufferBankwise::storeRequest(tlm::tlm_generic_payload *payload) +{ + lastBankID = DramExtension::getBank(payload).ID(); + requestsOnBank[lastBankID]++; +} + +void BufferBankwise::removeRequest(tlm::tlm_generic_payload *payload) +{ + requestsOnBank[DramExtension::getBank(payload).ID()]--; +} diff --git a/DRAMSys/library/src/controller/scheduler/BufferBankwise.h b/DRAMSys/library/src/controller/scheduler/BufferBankwise.h new file mode 100644 index 00000000..3fd63490 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferBankwise.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#ifndef BUFFERBANKWISE_H +#define BUFFERBANKWISE_H + +#include + +#include "BufferIF.h" + +class BufferBankwise : public BufferIF +{ +public: + BufferBankwise(unsigned requestBufferSize, unsigned numberOfBanks); + virtual bool hasBufferSpace() const override; + virtual void storeRequest(tlm::tlm_generic_payload *payload) override; + virtual void removeRequest(tlm::tlm_generic_payload *payload) override; + +private: + const unsigned requestBufferSize; + std::vector requestsOnBank; + unsigned lastBankID; +}; + +#endif // BUFFERBANKWISE_H diff --git a/DRAMSys/library/src/controller/scheduler/BufferIF.h b/DRAMSys/library/src/controller/scheduler/BufferIF.h new file mode 100644 index 00000000..6c8349ae --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferIF.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#ifndef BUFFERIF_H +#define BUFFERIF_H + +#include + +class BufferIF +{ +public: + virtual bool hasBufferSpace() const = 0; + virtual void storeRequest(tlm::tlm_generic_payload *payload) = 0; + virtual void removeRequest(tlm::tlm_generic_payload *payload) = 0; +}; + +#endif // BUFFERIF_H diff --git a/DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp b/DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp new file mode 100644 index 00000000..62fdf772 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferReadWrite.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#include "BufferReadWrite.h" + +BufferReadWrite::BufferReadWrite(unsigned requestBufferSize) + : requestBufferSize(requestBufferSize) {} + +bool BufferReadWrite::hasBufferSpace() const +{ + return (numberOfReads < requestBufferSize && numberOfWrites < requestBufferSize); +} + +void BufferReadWrite::storeRequest(tlm::tlm_generic_payload *payload) +{ + if (payload->is_read()) + numberOfReads++; + else + numberOfWrites++; +} + +void BufferReadWrite::removeRequest(tlm::tlm_generic_payload *payload) +{ + if (payload->is_read()) + numberOfReads--; + else + numberOfWrites--; +} diff --git a/DRAMSys/library/src/controller/scheduler/BufferReadWrite.h b/DRAMSys/library/src/controller/scheduler/BufferReadWrite.h new file mode 100644 index 00000000..32835c74 --- /dev/null +++ b/DRAMSys/library/src/controller/scheduler/BufferReadWrite.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, 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. + * + * Author: Lukas Steiner + */ + +#ifndef BUFFERREADWRITE_H +#define BUFFERREADWRITE_H + +#include "BufferIF.h" + +class BufferReadWrite : public BufferIF +{ +public: + BufferReadWrite(unsigned requestBufferSize); + virtual bool hasBufferSpace() const override; + virtual void storeRequest(tlm::tlm_generic_payload *payload) override; + virtual void removeRequest(tlm::tlm_generic_payload *payload) override; + +private: + const unsigned requestBufferSize; + unsigned numberOfReads = 0; + unsigned numberOfWrites = 0; +}; + +#endif // BUFFERREADWRITE_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp index f90c1c95..ab9fa81e 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.cpp @@ -34,58 +34,62 @@ #include "SchedulerFifo.h" #include "../../configuration/Configuration.h" +#include "BufferBankwise.h" +#include "BufferReadWrite.h" using namespace tlm; SchedulerFifo::SchedulerFifo() { - buffer = std::vector> - (Configuration::getInstance().memSpec->numberOfBanks); - requestBufferSize = Configuration::getInstance().requestBufferSize; + Configuration &config = Configuration::getInstance(); + localBuffer = std::vector>(config.memSpec->numberOfBanks); + + if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) + buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) + buffer = new BufferReadWrite(config.requestBufferSize); } -bool SchedulerFifo::hasBufferSpace() +bool SchedulerFifo::hasBufferSpace() const { - if (buffer[lastBankID].size() < requestBufferSize) - return true; - else - return false; + return buffer->hasBufferSpace(); } void SchedulerFifo::storeRequest(tlm_generic_payload *payload) { - lastBankID = DramExtension::getBank(payload).ID(); - buffer[lastBankID].push_back(payload); + localBuffer[DramExtension::getBank(payload).ID()].push_back(payload); + buffer->storeRequest(payload); } void SchedulerFifo::removeRequest(tlm_generic_payload *payload) { - buffer[DramExtension::getBank(payload).ID()].pop_front(); + localBuffer[DramExtension::getBank(payload).ID()].pop_front(); + buffer->removeRequest(payload); } -tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) +tlm_generic_payload *SchedulerFifo::getNextRequest(BankMachine *bankMachine) const { unsigned bankID = bankMachine->getBank().ID(); - if (!buffer[bankID].empty()) - return buffer[bankID].front(); + if (!localBuffer[bankID].empty()) + return localBuffer[bankID].front(); else return nullptr; } -bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) +bool SchedulerFifo::hasFurtherRowHit(Bank bank, Row row) const { - if (buffer[bank.ID()].size() >= 2) + if (localBuffer[bank.ID()].size() >= 2) { - tlm_generic_payload *nextRequest = buffer[bank.ID()][1]; + tlm_generic_payload *nextRequest = localBuffer[bank.ID()][1]; if (DramExtension::getRow(nextRequest) == row) return true; } return false; } -bool SchedulerFifo::hasFurtherRequest(Bank bank) +bool SchedulerFifo::hasFurtherRequest(Bank bank) const { - if (buffer[bank.ID()].size() >= 2) + if (localBuffer[bank.ID()].size() >= 2) return true; else return false; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h index aacbb1e8..c34a095a 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFifo.h @@ -38,24 +38,26 @@ #include #include #include + #include "SchedulerIF.h" #include "../../common/dramExtensions.h" #include "../BankMachine.h" +#include "BufferIF.h" class SchedulerFifo : public SchedulerIF { public: SchedulerFifo(); - virtual bool hasBufferSpace() override; + virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *) override; virtual void removeRequest(tlm::tlm_generic_payload *) override; - virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) override; - virtual bool hasFurtherRowHit(Bank, Row) override; - virtual bool hasFurtherRequest(Bank) override; + virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; + virtual bool hasFurtherRowHit(Bank, Row) const override; + virtual bool hasFurtherRequest(Bank) const override; + private: - std::vector> buffer; - unsigned requestBufferSize; - unsigned lastBankID; + std::vector> localBuffer; + BufferIF *buffer; }; #endif // SCHEDULERFIFO_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp index de91e8b4..8c0b02c8 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.cpp @@ -33,72 +33,73 @@ */ #include "SchedulerFrFcfs.h" - #include "../../configuration/Configuration.h" -#include +#include "BufferBankwise.h" +#include "BufferReadWrite.h" using namespace tlm; SchedulerFrFcfs::SchedulerFrFcfs() { - buffer = std::vector> - (Configuration::getInstance().memSpec->numberOfBanks); - requestBufferSize = Configuration::getInstance().requestBufferSize; + Configuration &config = Configuration::getInstance(); + localBuffer = std::vector>(config.memSpec->numberOfBanks); + + if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) + buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) + buffer = new BufferReadWrite(config.requestBufferSize); } -bool SchedulerFrFcfs::hasBufferSpace() +bool SchedulerFrFcfs::hasBufferSpace() const { - if (buffer[lastBankID].size() < requestBufferSize) - return true; - else - return false; + return buffer->hasBufferSpace(); } void SchedulerFrFcfs::storeRequest(tlm_generic_payload *payload) { - lastBankID = DramExtension::getBank(payload).ID(); - buffer[lastBankID].push_back(payload); + localBuffer[DramExtension::getBank(payload).ID()].push_back(payload); + buffer->storeRequest(payload); } void SchedulerFrFcfs::removeRequest(tlm_generic_payload *payload) { + buffer->removeRequest(payload); unsigned bankID = DramExtension::getBank(payload).ID(); - for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) + for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) { if (*it == payload) { - buffer[bankID].erase(it); - return; + localBuffer[bankID].erase(it); + break; } } - SC_REPORT_FATAL("SchedulerFrFcfs", "removeRequest failed!"); } -tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) +tlm_generic_payload *SchedulerFrFcfs::getNextRequest(BankMachine *bankMachine) const { unsigned bankID = bankMachine->getBank().ID(); - if (!buffer[bankID].empty()) + if (!localBuffer[bankID].empty()) { if (bankMachine->getState() == BmState::Activated) { // Search for row hit Row openRow = bankMachine->getOpenRow(); - for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) + for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) { if (DramExtension::getRow(*it) == openRow) return *it; } } // No row hit found or bank precharged - return buffer[bankID].front(); + return localBuffer[bankID].front(); } return nullptr; } -bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) +bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) const { unsigned rowHitCounter = 0; - for (auto it = buffer[bank.ID()].begin(); it != buffer[bank.ID()].end(); it++) + for (auto it = localBuffer[bank.ID()].begin(); it != localBuffer[bank.ID()].end(); it++) { if (DramExtension::getRow(*it) == row) { @@ -110,7 +111,7 @@ bool SchedulerFrFcfs::hasFurtherRowHit(Bank bank, Row row) return false; } -bool SchedulerFrFcfs::hasFurtherRequest(Bank bank) +bool SchedulerFrFcfs::hasFurtherRequest(Bank bank) const { - return (buffer[bank.ID()].size() >= 2); + return (localBuffer[bank.ID()].size() >= 2); } diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h index 5d5347a4..d8413b2a 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfs.h @@ -38,24 +38,26 @@ #include #include #include + #include "SchedulerIF.h" #include "../../common/dramExtensions.h" #include "../BankMachine.h" +#include "BufferIF.h" class SchedulerFrFcfs : public SchedulerIF { public: SchedulerFrFcfs(); - virtual bool hasBufferSpace() override; + virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *) override; virtual void removeRequest(tlm::tlm_generic_payload *) override; - virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) override; - virtual bool hasFurtherRowHit(Bank, Row) override; - virtual bool hasFurtherRequest(Bank) override; + virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; + virtual bool hasFurtherRowHit(Bank, Row) const override; + virtual bool hasFurtherRequest(Bank) const override; + private: - std::vector> buffer; - unsigned requestBufferSize; - unsigned lastBankID; + std::vector> localBuffer; + BufferIF *buffer; }; #endif // SCHEDULERFRFCFS_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp index 8af96e96..b9cb739d 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.cpp @@ -34,56 +34,59 @@ #include "SchedulerFrFcfsGrp.h" #include "../../configuration/Configuration.h" +#include "BufferBankwise.h" +#include "BufferReadWrite.h" using namespace tlm; SchedulerFrFcfsGrp::SchedulerFrFcfsGrp() { - buffer = std::vector> - (Configuration::getInstance().memSpec->numberOfBanks); - requestBufferSize = Configuration::getInstance().requestBufferSize; + Configuration &config = Configuration::getInstance(); + localBuffer = std::vector>(config.memSpec->numberOfBanks); + + if (config.schedulerBuffer == Configuration::SchedulerBuffer::Bankwise) + buffer = new BufferBankwise(config.requestBufferSize, config.memSpec->numberOfBanks); + else if (config.schedulerBuffer == Configuration::SchedulerBuffer::ReadWrite) + buffer = new BufferReadWrite(config.requestBufferSize); } -bool SchedulerFrFcfsGrp::hasBufferSpace() +bool SchedulerFrFcfsGrp::hasBufferSpace() const { - if (buffer[lastBankID].size() < requestBufferSize) - return true; - else - return false; + return buffer->hasBufferSpace(); } void SchedulerFrFcfsGrp::storeRequest(tlm_generic_payload *payload) { - lastBankID = DramExtension::getBank(payload).ID(); - buffer[lastBankID].push_back(payload); + localBuffer[DramExtension::getBank(payload).ID()].push_back(payload); + buffer->storeRequest(payload); } void SchedulerFrFcfsGrp::removeRequest(tlm_generic_payload *payload) { + buffer->removeRequest(payload); lastCommand = payload->get_command(); unsigned bankID = DramExtension::getBank(payload).ID(); - for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) + for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) { if (*it == payload) { - buffer[bankID].erase(it); - return; + localBuffer[bankID].erase(it); + break; } } - SC_REPORT_FATAL("SchedulerFrFcfs", "removeRequest failed!"); } -tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine) +tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine) const { unsigned bankID = bankMachine->getBank().ID(); - if (!buffer[bankID].empty()) + if (!localBuffer[bankID].empty()) { if (bankMachine->getState() == BmState::Activated) { // Filter all row hits Row openRow = bankMachine->getOpenRow(); std::list rowHits; - for (auto it = buffer[bankID].begin(); it != buffer[bankID].end(); it++) + for (auto it = localBuffer[bankID].begin(); it != localBuffer[bankID].end(); it++) { if (DramExtension::getRow(*it) == openRow) rowHits.push_back(*it); @@ -113,15 +116,15 @@ tlm_generic_payload *SchedulerFrFcfsGrp::getNextRequest(BankMachine *bankMachine } } // No row hit found or bank precharged - return buffer[bankID].front(); + return localBuffer[bankID].front(); } return nullptr; } -bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) +bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) const { unsigned rowHitCounter = 0; - for (auto it = buffer[bank.ID()].begin(); it != buffer[bank.ID()].end(); it++) + for (auto it = localBuffer[bank.ID()].begin(); it != localBuffer[bank.ID()].end(); it++) { if (DramExtension::getRow(*it) == row) { @@ -133,9 +136,9 @@ bool SchedulerFrFcfsGrp::hasFurtherRowHit(Bank bank, Row row) return false; } -bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank) +bool SchedulerFrFcfsGrp::hasFurtherRequest(Bank bank) const { - if (buffer[bank.ID()].size() >= 2) + if (localBuffer[bank.ID()].size() >= 2) return true; else return false; diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h index 34ca4472..af2e6ad4 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerFrFcfsGrp.h @@ -42,22 +42,23 @@ #include "SchedulerIF.h" #include "../../common/dramExtensions.h" #include "../BankMachine.h" +#include "BufferIF.h" class SchedulerFrFcfsGrp : public SchedulerIF { public: SchedulerFrFcfsGrp(); - virtual bool hasBufferSpace() override; + virtual bool hasBufferSpace() const override; virtual void storeRequest(tlm::tlm_generic_payload *) override; virtual void removeRequest(tlm::tlm_generic_payload *) override; - virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) override; - virtual bool hasFurtherRowHit(Bank, Row) override; - virtual bool hasFurtherRequest(Bank) override; + virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const override; + virtual bool hasFurtherRowHit(Bank, Row) const override; + virtual bool hasFurtherRequest(Bank) const override; + private: - std::vector> buffer; - unsigned requestBufferSize; + std::vector> localBuffer; tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND; - unsigned lastBankID; + BufferIF *buffer; }; #endif // SCHEDULERFRFCFSGRP_H diff --git a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h index c069a5cb..f82ea208 100644 --- a/DRAMSys/library/src/controller/scheduler/SchedulerIF.h +++ b/DRAMSys/library/src/controller/scheduler/SchedulerIF.h @@ -36,6 +36,7 @@ #define SCHEDULERIF_H #include + #include "../../common/dramExtensions.h" #include "../../common/DebugManager.h" @@ -46,12 +47,12 @@ class SchedulerIF { public: virtual ~SchedulerIF() {} - virtual bool hasBufferSpace() = 0; + virtual bool hasBufferSpace() const = 0; virtual void storeRequest(tlm::tlm_generic_payload *) = 0; virtual void removeRequest(tlm::tlm_generic_payload *) = 0; - virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) = 0; - virtual bool hasFurtherRowHit(Bank, Row) = 0; - virtual bool hasFurtherRequest(Bank) = 0; + virtual tlm::tlm_generic_payload *getNextRequest(BankMachine *) const = 0; + virtual bool hasFurtherRowHit(Bank, Row) const = 0; + virtual bool hasFurtherRequest(Bank) const = 0; }; #endif // SCHEDULERIF_H diff --git a/DRAMSys/library/src/error/errormodel.cpp b/DRAMSys/library/src/error/errormodel.cpp index 42e1d0d1..0195f194 100644 --- a/DRAMSys/library/src/error/errormodel.cpp +++ b/DRAMSys/library/src/error/errormodel.cpp @@ -36,7 +36,7 @@ #include "errormodel.h" #include "../common/DebugManager.h" #include "../simulation/TemperatureController.h" -#include "../common/AddressDecoder.h" +#include "../simulation/AddressDecoder.h" #include "../common/dramExtensions.h" #include @@ -51,7 +51,7 @@ void errorModel::init() // Get Configuration parameters: burstLenght = Configuration::getInstance().memSpec->burstLength; numberOfColumns = Configuration::getInstance().memSpec->numberOfColumns; - bytesPerColumn = std::log2(Configuration::getInstance().getDataBusWidth()); + bytesPerColumn = std::log2(Configuration::getInstance().memSpec->dataBusWidth); // Adjust number of bytes per column dynamically to the selected ecc controller bytesPerColumn = Configuration::getInstance().adjustNumBytesAfterECC( diff --git a/DRAMSys/library/src/error/errormodel.h b/DRAMSys/library/src/error/errormodel.h index 99598d9c..99fdd034 100644 --- a/DRAMSys/library/src/error/errormodel.h +++ b/DRAMSys/library/src/error/errormodel.h @@ -40,7 +40,7 @@ #include #include #include "../configuration/Configuration.h" -#include "../common/AddressDecoder.h" +#include "../simulation/AddressDecoder.h" #include "../common/third_party/DRAMPower/src/libdrampower/LibDRAMPower.h" class errorModel : public sc_module diff --git a/DRAMSys/library/src/common/AddressDecoder.cpp b/DRAMSys/library/src/simulation/AddressDecoder.cpp similarity index 99% rename from DRAMSys/library/src/common/AddressDecoder.cpp rename to DRAMSys/library/src/simulation/AddressDecoder.cpp index b6c9cdd4..f4bf0400 100644 --- a/DRAMSys/library/src/common/AddressDecoder.cpp +++ b/DRAMSys/library/src/simulation/AddressDecoder.cpp @@ -39,7 +39,7 @@ #include #include "AddressDecoder.h" -#include "utils.h" +#include "../common/utils.h" #include "../configuration/Configuration.h" using json = nlohmann::json; diff --git a/DRAMSys/library/src/common/AddressDecoder.h b/DRAMSys/library/src/simulation/AddressDecoder.h similarity index 100% rename from DRAMSys/library/src/common/AddressDecoder.h rename to DRAMSys/library/src/simulation/AddressDecoder.h diff --git a/DRAMSys/library/src/simulation/Arbiter.cpp b/DRAMSys/library/src/simulation/Arbiter.cpp index 8ed91d8e..c95212cd 100644 --- a/DRAMSys/library/src/simulation/Arbiter.cpp +++ b/DRAMSys/library/src/simulation/Arbiter.cpp @@ -36,7 +36,7 @@ */ #include "Arbiter.h" -#include "../common/AddressDecoder.h" +#include "AddressDecoder.h" #include "../configuration/Configuration.h" using namespace tlm; diff --git a/DRAMSys/library/src/simulation/Arbiter.h b/DRAMSys/library/src/simulation/Arbiter.h index c2c83222..0919f9a9 100644 --- a/DRAMSys/library/src/simulation/Arbiter.h +++ b/DRAMSys/library/src/simulation/Arbiter.h @@ -47,7 +47,7 @@ #include #include #include -#include "../common/AddressDecoder.h" +#include "AddressDecoder.h" #include "../common/dramExtensions.h" class Arbiter : public sc_module diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 4b3317db..e8d807f9 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -184,24 +184,23 @@ void DRAMSys::instantiateModules(const std::string &pathToResources, // The first call to getInstance() creates the Temperature Controller. // The same instance will be accessed by all other modules. TemperatureController::getInstance(); + Configuration &config = Configuration::getInstance(); // Create new ECC Controller - if (Configuration::getInstance().ECCMode == "Hamming") + if (config.eccMode == Configuration::ECCMode::Hamming) ecc = new ECCHamming("ECCHamming"); - else if (Configuration::getInstance().ECCMode == "Disabled") + else if (config.eccMode == Configuration::ECCMode::Disabled) ecc = nullptr; - else - SC_REPORT_FATAL("DRAMSys", "Unsupported ECC mode"); // Save ECC Controller into the configuration struct to adjust it dynamically - Configuration::getInstance().pECC = ecc; + config.pECC = ecc; // Create arbiter arbiter = new Arbiter("arbiter", pathToResources + "configs/amconfigs/" + amconfig); // Create controllers and DRAMs - std::string memoryType = Configuration::getInstance().memSpec->memoryType; - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) + MemSpec::MemoryType memoryType = config.memSpec->memoryType; + for (size_t i = 0; i < config.memSpec->numberOfChannels; i++) { std::string str = "controller" + std::to_string(i); @@ -211,28 +210,26 @@ void DRAMSys::instantiateModules(const std::string &pathToResources, str = "dram" + std::to_string(i); Dram *dram; - if (memoryType == "DDR3") + if (memoryType == MemSpec::MemoryType::DDR3) dram = new DramDDR3(str.c_str()); - else if (memoryType == "WIDEIO_SDR") - dram = new DramWideIO(str.c_str()); - else if (memoryType == "DDR4") + else if (memoryType == MemSpec::MemoryType::DDR4) dram = new DramDDR4(str.c_str()); - else if (memoryType == "DDR5") + else if (memoryType == MemSpec::MemoryType::DDR5) dram = new DramDDR5(str.c_str()); - else if (memoryType == "LPDDR4") + else if (memoryType == MemSpec::MemoryType::WideIO) + dram = new DramWideIO(str.c_str()); + else if (memoryType == MemSpec::MemoryType::LPDDR4) dram = new DramLPDDR4(str.c_str()); - else if (memoryType == "WIDEIO2") + else if (memoryType == MemSpec::MemoryType::WideIO2) dram = new DramWideIO2(str.c_str()); - else if (memoryType == "HBM2") + else if (memoryType == MemSpec::MemoryType::HBM2) dram = new DramHBM2(str.c_str()); - else if (memoryType == "GDDR5") + else if (memoryType == MemSpec::MemoryType::GDDR5) dram = new DramGDDR5(str.c_str()); - else if (memoryType == "GDDR5X") + else if (memoryType == MemSpec::MemoryType::GDDR5X) dram = new DramGDDR5X(str.c_str()); - else if (memoryType == "GDDR6") + else if (memoryType == MemSpec::MemoryType::GDDR6) dram = new DramGDDR6(str.c_str()); - else - SC_REPORT_FATAL("DRAMSys", "Unsupported DRAM type"); drams.push_back(dram); @@ -248,21 +245,21 @@ void DRAMSys::instantiateModules(const std::string &pathToResources, void DRAMSys::bindSockets() { + Configuration &config = Configuration::getInstance(); + // If ECC Controller enabled, put it between Trace and arbiter - if (Configuration::getInstance().ECCMode == "Hamming") + if (config.eccMode == Configuration::ECCMode::Hamming) { assert(ecc != nullptr); tSocket.bind(ecc->t_socket); ecc->i_socket.bind(arbiter->tSocket); } - else if (Configuration::getInstance().ECCMode == "Disabled") + else if (config.eccMode == Configuration::ECCMode::Disabled) tSocket.bind(arbiter->tSocket); - else - SC_REPORT_FATAL("DRAMSys", "Unsupported ECC mode"); - if (Configuration::getInstance().checkTLM2Protocol) + if (config.checkTLM2Protocol) { - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) + for (size_t i = 0; i < config.memSpec->numberOfChannels; i++) { arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); controllersTlmCheckers[i]->initiator_socket.bind(controllers[i]->tSocket); @@ -271,7 +268,7 @@ void DRAMSys::bindSockets() } else { - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) + for (size_t i = 0; i < config.memSpec->numberOfChannels; i++) { arbiter->iSocket.bind(controllers[i]->tSocket); controllers[i]->iSocket.bind(drams[i]->tSocket); diff --git a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp index 70631100..2c57a010 100644 --- a/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp +++ b/DRAMSys/library/src/simulation/DRAMSysRecordable.cpp @@ -121,27 +121,27 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, // The same instance will be accessed by all other modules. TemperatureController::getInstance(); + Configuration &config = Configuration::getInstance(); + // Create and properly initialize TLM recorders. // They need to be ready before creating some modules. setupTlmRecorders(traceName, pathToResources); // Create new ECC Controller - if (Configuration::getInstance().ECCMode == "Hamming") + if (config.eccMode == Configuration::ECCMode::Hamming) ecc = new ECCHamming("ECCHamming"); - else if (Configuration::getInstance().ECCMode == "Disabled") + else if (config.eccMode == Configuration::ECCMode::Disabled) ecc = nullptr; - else - SC_REPORT_FATAL("DRAMSys", "Unsupported ECC mode"); // Save ECC Controller into the configuration struct to adjust it dynamically - Configuration::getInstance().pECC = ecc; + config.pECC = ecc; // Create arbiter arbiter = new Arbiter("arbiter", pathToResources + "configs/amconfigs/" + amconfig); // Create controllers and DRAMs - std::string memoryType = Configuration::getInstance().memSpec->memoryType; - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) + MemSpec::MemoryType memoryType = config.memSpec->memoryType; + for (size_t i = 0; i < config.memSpec->numberOfChannels; i++) { std::string str = "controller" + std::to_string(i); @@ -151,32 +151,30 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, str = "dram" + std::to_string(i); Dram *dram; - if (memoryType == "DDR3") + if (memoryType == MemSpec::MemoryType::DDR3) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "DDR4") + else if (memoryType == MemSpec::MemoryType::DDR4) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "DDR5") + else if (memoryType == MemSpec::MemoryType::DDR5) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "LPDDR4") - dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "WIDEIO_SDR") + else if (memoryType == MemSpec::MemoryType::WideIO) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "WIDEIO2") + else if (memoryType == MemSpec::MemoryType::LPDDR4) + dram = new DramRecordable(str.c_str(), tlmRecorders[i]); + else if (memoryType == MemSpec::MemoryType::WideIO2) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "HBM2") + else if (memoryType == MemSpec::MemoryType::HBM2) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "GDDR5") + else if (memoryType == MemSpec::MemoryType::GDDR5) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "GDDR5X") + else if (memoryType == MemSpec::MemoryType::GDDR5X) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else if (memoryType == "GDDR6") + else if (memoryType == MemSpec::MemoryType::GDDR6) dram = new DramRecordable(str.c_str(), tlmRecorders[i]); - else - SC_REPORT_FATAL("DRAMSys", "Unsupported DRAM type"); drams.push_back(dram); - if (Configuration::getInstance().checkTLM2Protocol) + if (config.checkTLM2Protocol) { str = "TLMCheckerController" + std::to_string(i); tlm_utils::tlm2_base_protocol_checker<> *controllerTlmChecker = @@ -188,21 +186,21 @@ void DRAMSysRecordable::instantiateModules(const std::string &traceName, void DRAMSysRecordable::bindSockets() { + Configuration &config = Configuration::getInstance(); + // If ECC Controller enabled, put it between Trace and arbiter - if (Configuration::getInstance().ECCMode == "Hamming") + if (config.eccMode == Configuration::ECCMode::Hamming) { assert(ecc != nullptr); tSocket.bind(ecc->t_socket); ecc->i_socket.bind(arbiter->tSocket); } - else if (Configuration::getInstance().ECCMode == "Disabled") + else if (config.eccMode == Configuration::ECCMode::Disabled) tSocket.bind(arbiter->tSocket); - else - SC_REPORT_FATAL("DRAMSys", "Unsupported ECC mode"); - if (Configuration::getInstance().checkTLM2Protocol) + if (config.checkTLM2Protocol) { - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) + for (size_t i = 0; i < config.memSpec->numberOfChannels; i++) { arbiter->iSocket.bind(controllersTlmCheckers[i]->target_socket); controllersTlmCheckers[i]->initiator_socket.bind(controllers[i]->tSocket); @@ -211,7 +209,7 @@ void DRAMSysRecordable::bindSockets() } else { - for (size_t i = 0; i < Configuration::getInstance().memSpec->numberOfChannels; i++) + for (size_t i = 0; i < config.memSpec->numberOfChannels; i++) { arbiter->iSocket.bind(controllers[i]->tSocket); controllers[i]->iSocket.bind(drams[i]->tSocket); diff --git a/DRAMSys/library/src/simulation/dram/Dram.cpp b/DRAMSys/library/src/simulation/dram/Dram.cpp index a18098be..b19d34b1 100644 --- a/DRAMSys/library/src/simulation/dram/Dram.cpp +++ b/DRAMSys/library/src/simulation/dram/Dram.cpp @@ -69,19 +69,12 @@ Dram::Dram(sc_module_name name) : sc_module(name), tSocket("socket") // Adjust number of bytes per burst dynamically to the selected ecc controller bytesPerBurst = config.adjustNumBytesAfterECC(bytesPerBurst); - if (config.storeMode == "NoStorage") - storeMode = StorageMode::NoStorage; - else if (config.storeMode == "Store") - storeMode = StorageMode::Store; - else if (config.storeMode == "ErrorModel") - storeMode = StorageMode::ErrorModel; - else - SC_REPORT_FATAL(this->name(), "Unsupported storage mode"); + storeMode = config.storeMode; - uint64_t memorySize = Configuration::getInstance().getSimMemSizeInBytes(); - if (storeMode == StorageMode::Store) + uint64_t memorySize = config.memSpec->getSimMemSizeInBytes(); + if (storeMode == Configuration::StoreMode::Store) { - if (Configuration::getInstance().useMalloc) + if (config.useMalloc) { memory = (unsigned char *)malloc(memorySize); if (!memory) @@ -151,7 +144,7 @@ tlm_sync_enum Dram::nb_transport_fw(tlm_generic_payload &payload, DRAMPower->doCommand(phaseToDRAMPowerCommand(phase), bank, cycle); } - if (storeMode == StorageMode::Store) + if (storeMode == Configuration::StoreMode::Store) { if (phase == BEGIN_RD || phase == BEGIN_RDA) { @@ -173,7 +166,7 @@ unsigned int Dram::transport_dbg(tlm_generic_payload &trans) PRINTDEBUGMESSAGE(name(), "transport_dgb"); // TODO: This part is not tested yet, neither with traceplayers nor with GEM5 coupling - if (storeMode == StorageMode::NoStorage) + if (storeMode == Configuration::StoreMode::NoStorage) { SC_REPORT_FATAL("DRAM", "Debug Transport is used in combination with NoStorage"); @@ -190,7 +183,7 @@ unsigned int Dram::transport_dbg(tlm_generic_payload &trans) if (cmd == TLM_READ_COMMAND) { - if (storeMode == StorageMode::Store) + if (storeMode == Configuration::StoreMode::Store) { // Use Storage unsigned char *phyAddr = memory + trans.get_address(); memcpy(ptr, phyAddr, trans.get_data_length()); @@ -203,7 +196,7 @@ unsigned int Dram::transport_dbg(tlm_generic_payload &trans) } else if (cmd == TLM_WRITE_COMMAND) { - if (storeMode == StorageMode::Store) + if (storeMode == Configuration::StoreMode::Store) { // Use Storage unsigned char *phyAddr = memory + trans.get_address(); memcpy(phyAddr, ptr, trans.get_data_length()); diff --git a/DRAMSys/library/src/simulation/dram/Dram.h b/DRAMSys/library/src/simulation/dram/Dram.h index d39d07b6..1d346e7a 100644 --- a/DRAMSys/library/src/simulation/dram/Dram.h +++ b/DRAMSys/library/src/simulation/dram/Dram.h @@ -50,7 +50,7 @@ class Dram : public sc_module { private: - unsigned int bytesPerBurst = Configuration::getInstance().getBytesPerBurst(); + unsigned int bytesPerBurst = Configuration::getInstance().memSpec->bytesPerBurst; bool powerReported = false; protected: @@ -60,7 +60,7 @@ protected: MemSpec *memSpec = Configuration::getInstance().memSpec; // Data Storage: - enum class StorageMode {NoStorage, Store, ErrorModel} storeMode; + Configuration::StoreMode storeMode; unsigned char *memory; diff --git a/DRAMSys/library/src/simulation/dram/DramDDR3.cpp b/DRAMSys/library/src/simulation/dram/DramDDR3.cpp index da039524..66e491df 100644 --- a/DRAMSys/library/src/simulation/dram/DramDDR3.cpp +++ b/DRAMSys/library/src/simulation/dram/DramDDR3.cpp @@ -44,7 +44,7 @@ using namespace DRAMPower; DramDDR3::DramDDR3(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramDDR3", "Error Model not supported for DDR3"); if (Configuration::getInstance().powerAnalysis) @@ -134,7 +134,7 @@ DramDDR3::DramDDR3(sc_module_name name) : Dram(name) MemorySpecification powerSpec; powerSpec.id = memSpec->memoryId; - powerSpec.memoryType = memSpec->memoryType; + powerSpec.memoryType = MemoryType::DDR3; powerSpec.memTimingSpec = memTimingSpec; powerSpec.memPowerSpec = memPowerSpec; powerSpec.memArchSpec = memArchSpec; diff --git a/DRAMSys/library/src/simulation/dram/DramDDR4.cpp b/DRAMSys/library/src/simulation/dram/DramDDR4.cpp index 751f4e30..82255616 100644 --- a/DRAMSys/library/src/simulation/dram/DramDDR4.cpp +++ b/DRAMSys/library/src/simulation/dram/DramDDR4.cpp @@ -44,7 +44,7 @@ using namespace DRAMPower; DramDDR4::DramDDR4(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramDDR4", "Error Model not supported for DDR4"); if (Configuration::getInstance().powerAnalysis) @@ -134,7 +134,7 @@ DramDDR4::DramDDR4(sc_module_name name) : Dram(name) MemorySpecification powerSpec; powerSpec.id = memSpec->memoryId; - powerSpec.memoryType = memSpec->memoryType; + powerSpec.memoryType = MemoryType::DDR4; powerSpec.memTimingSpec = memTimingSpec; powerSpec.memPowerSpec = memPowerSpec; powerSpec.memArchSpec = memArchSpec; diff --git a/DRAMSys/library/src/simulation/dram/DramDDR5.cpp b/DRAMSys/library/src/simulation/dram/DramDDR5.cpp index c794e9c0..8b10e911 100644 --- a/DRAMSys/library/src/simulation/dram/DramDDR5.cpp +++ b/DRAMSys/library/src/simulation/dram/DramDDR5.cpp @@ -44,7 +44,7 @@ using namespace DRAMPower; DramDDR5::DramDDR5(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramDDR5", "Error Model not supported for DDR5"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/library/src/simulation/dram/DramGDDR5.cpp b/DRAMSys/library/src/simulation/dram/DramGDDR5.cpp index 552ff81d..e3fe6014 100644 --- a/DRAMSys/library/src/simulation/dram/DramGDDR5.cpp +++ b/DRAMSys/library/src/simulation/dram/DramGDDR5.cpp @@ -42,7 +42,7 @@ DramGDDR5::DramGDDR5(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramGDDR5", "Error Model not supported for GDDR5"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/library/src/simulation/dram/DramGDDR5X.cpp b/DRAMSys/library/src/simulation/dram/DramGDDR5X.cpp index 7db5f265..3c767638 100644 --- a/DRAMSys/library/src/simulation/dram/DramGDDR5X.cpp +++ b/DRAMSys/library/src/simulation/dram/DramGDDR5X.cpp @@ -42,7 +42,7 @@ DramGDDR5X::DramGDDR5X(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramGDDR5X", "Error Model not supported for GDDR5X"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/library/src/simulation/dram/DramGDDR6.cpp b/DRAMSys/library/src/simulation/dram/DramGDDR6.cpp index a144c211..24fbed6f 100644 --- a/DRAMSys/library/src/simulation/dram/DramGDDR6.cpp +++ b/DRAMSys/library/src/simulation/dram/DramGDDR6.cpp @@ -42,7 +42,7 @@ DramGDDR6::DramGDDR6(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramGDDR6", "Error Model not supported for GDDR6"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/library/src/simulation/dram/DramHBM2.cpp b/DRAMSys/library/src/simulation/dram/DramHBM2.cpp index a803d1a6..1dec6977 100644 --- a/DRAMSys/library/src/simulation/dram/DramHBM2.cpp +++ b/DRAMSys/library/src/simulation/dram/DramHBM2.cpp @@ -42,7 +42,7 @@ DramHBM2::DramHBM2(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramHBM2", "Error Model not supported for HBM2"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/library/src/simulation/dram/DramLPDDR4.cpp b/DRAMSys/library/src/simulation/dram/DramLPDDR4.cpp index de60b0da..503d2774 100644 --- a/DRAMSys/library/src/simulation/dram/DramLPDDR4.cpp +++ b/DRAMSys/library/src/simulation/dram/DramLPDDR4.cpp @@ -42,7 +42,7 @@ DramLPDDR4::DramLPDDR4(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramLPDDR4", "Error Model not supported for LPDDR4"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/library/src/simulation/dram/DramWideIO.cpp b/DRAMSys/library/src/simulation/dram/DramWideIO.cpp index eeb78d01..1f9b7a79 100644 --- a/DRAMSys/library/src/simulation/dram/DramWideIO.cpp +++ b/DRAMSys/library/src/simulation/dram/DramWideIO.cpp @@ -135,7 +135,7 @@ DramWideIO::DramWideIO(sc_module_name name) : Dram(name) MemorySpecification powerSpec; powerSpec.id = memSpec->memoryId; - powerSpec.memoryType = memSpec->memoryType; + powerSpec.memoryType = MemoryType::WIDEIO_SDR; powerSpec.memTimingSpec = memTimingSpec; powerSpec.memPowerSpec = memPowerSpec; powerSpec.memArchSpec = memArchSpec; @@ -143,7 +143,7 @@ DramWideIO::DramWideIO(sc_module_name name) : Dram(name) DRAMPower = new libDRAMPower(powerSpec, 0); // For each bank in a channel a error Model is created: - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) { for (unsigned i = 0; i < memSpec->numberOfBanks; i++) { @@ -156,7 +156,7 @@ DramWideIO::DramWideIO(sc_module_name name) : Dram(name) } else { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) { for (unsigned i = 0; i < memSpec->numberOfBanks; i++) { @@ -188,7 +188,7 @@ tlm_sync_enum DramWideIO::nb_transport_fw(tlm_generic_payload &payload, DRAMPower->doCommand(phaseToDRAMPowerCommand(phase), bank, cycle); } - if (storeMode == StorageMode::Store) + if (storeMode == Configuration::StoreMode::Store) { if (phase == BEGIN_RD || phase == BEGIN_RDA) { @@ -201,7 +201,7 @@ tlm_sync_enum DramWideIO::nb_transport_fw(tlm_generic_payload &payload, memcpy(phyAddr, payload.get_data_ptr(), payload.get_data_length()); } } - else if (storeMode == StorageMode::ErrorModel) + else if (storeMode == Configuration::StoreMode::ErrorModel) { unsigned bank = DramExtension::getExtension(payload).getBank().ID(); diff --git a/DRAMSys/library/src/simulation/dram/DramWideIO2.cpp b/DRAMSys/library/src/simulation/dram/DramWideIO2.cpp index aba04086..2dbce0cc 100644 --- a/DRAMSys/library/src/simulation/dram/DramWideIO2.cpp +++ b/DRAMSys/library/src/simulation/dram/DramWideIO2.cpp @@ -42,7 +42,7 @@ DramWideIO2::DramWideIO2(sc_module_name name) : Dram(name) { - if (storeMode == StorageMode::ErrorModel) + if (storeMode == Configuration::StoreMode::ErrorModel) SC_REPORT_FATAL("DramWideIO2", "Error Model not supported for WideIO2"); if (Configuration::getInstance().powerAnalysis) diff --git a/DRAMSys/simulator/MemoryManager.cpp b/DRAMSys/simulator/MemoryManager.cpp index 361b3f68..bfb64e82 100644 --- a/DRAMSys/simulator/MemoryManager.cpp +++ b/DRAMSys/simulator/MemoryManager.cpp @@ -44,7 +44,7 @@ using namespace tlm; MemoryManager::MemoryManager() : numberOfAllocations(0), numberOfFrees(0) { - if (Configuration::getInstance().storeMode == "NoStorage") + if (Configuration::getInstance().storeMode == Configuration::StoreMode::NoStorage) storageEnabled = false; else storageEnabled = true; @@ -80,7 +80,7 @@ tlm_generic_payload *MemoryManager::allocate() if (storageEnabled) { // Allocate a data buffer and initialize it with zeroes: - unsigned int dataLength = Configuration::getInstance().getBytesPerBurst(); + unsigned int dataLength = Configuration::getInstance().memSpec->bytesPerBurst; unsigned char *data = new unsigned char[dataLength]; std::fill(data, data + dataLength, 0); payload->set_data_ptr(data); diff --git a/DRAMSys/simulator/StlPlayer.cpp b/DRAMSys/simulator/StlPlayer.cpp index 4aa918ec..24fb7227 100644 --- a/DRAMSys/simulator/StlPlayer.cpp +++ b/DRAMSys/simulator/StlPlayer.cpp @@ -56,7 +56,7 @@ StlPlayer::StlPlayer(sc_module_name name, this->playerClk = playerClk; burstlength = Configuration::getInstance().memSpec->burstLength; - dataLength = Configuration::getInstance().getBytesPerBurst(); + dataLength = Configuration::getInstance().memSpec->bytesPerBurst; lineCnt = 0; currentBuffer->reserve(lineBufferSize); diff --git a/DRAMSys/simulator/TracePlayer.cpp b/DRAMSys/simulator/TracePlayer.cpp index 69e8b16a..dfdcf848 100644 --- a/DRAMSys/simulator/TracePlayer.cpp +++ b/DRAMSys/simulator/TracePlayer.cpp @@ -49,7 +49,7 @@ TracePlayer::TracePlayer(sc_module_name name, TraceSetup *setup) : SC_METHOD(nextPayload); iSocket.register_nb_transport_bw(this, &TracePlayer::nb_transport_bw); - if (Configuration::getInstance().storeMode == "NoStorage") + if (Configuration::getInstance().storeMode == Configuration::StoreMode::NoStorage) storageEnabled = false; else storageEnabled = true;