Merge branch 'rambus_scheduler' into DDR5

# Conflicts:
#	DRAMSys/library/src/configuration/memspec/MemSpec.h
#	DRAMSys/library/src/controller/Controller.cpp
#	DRAMSys/library/src/simulation/DRAMSys.cpp
#	DRAMSys/library/src/simulation/DRAMSysRecordable.cpp
This commit is contained in:
Lukas Steiner
2020-10-26 08:37:59 +01:00
61 changed files with 885 additions and 333 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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);

View File

@@ -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<unsigned>(numberOfCommands(), 1);

View File

@@ -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,

View File

@@ -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<uint64_t>(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;
}

View File

@@ -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

View File

@@ -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<uint64_t>(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;
}

View File

@@ -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

View File

@@ -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<uint64_t>(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;
}

View File

@@ -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

View File

@@ -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<uint64_t>(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;
}

View File

@@ -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

View File

@@ -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<uint64_t>(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;
}

View File

@@ -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

View File

@@ -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<uint64_t>(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;
}

View File

@@ -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

View File

@@ -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<uint64_t>(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;
}

View File

@@ -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

View File

@@ -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<uint64_t>(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;
}

View File

@@ -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

View File

@@ -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<uint64_t>(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;
}

View File

@@ -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

View File

@@ -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<unsigned>(parseUint(memspec["memtimingspec"]["REFI"], "REFI")
* parseUdouble(memspec["memtimingspec"]["REFM"], "REFM"))),
tREFIpb (tCK * (unsigned)(parseUint(memspec["memtimingspec"]["REFIPB"], "REFIPB")
tREFIpb (tCK * static_cast<unsigned>(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<uint64_t>(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;
}

View File

@@ -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

View File

@@ -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++)
{

View File

@@ -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<unsigned>(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()]--;
}

View File

@@ -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 <vector>
#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<unsigned> requestsOnBank;
unsigned lastBankID;
};
#endif // BUFFERBANKWISE_H

View File

@@ -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 <tlm.h>
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

View File

@@ -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--;
}

View File

@@ -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

View File

@@ -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<std::deque<tlm_generic_payload *>>
(Configuration::getInstance().memSpec->numberOfBanks);
requestBufferSize = Configuration::getInstance().requestBufferSize;
Configuration &config = Configuration::getInstance();
localBuffer = std::vector<std::deque<tlm_generic_payload *>>(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;

View File

@@ -38,24 +38,26 @@
#include <tlm.h>
#include <vector>
#include <deque>
#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<std::deque<tlm::tlm_generic_payload *>> buffer;
unsigned requestBufferSize;
unsigned lastBankID;
std::vector<std::deque<tlm::tlm_generic_payload *>> localBuffer;
BufferIF *buffer;
};
#endif // SCHEDULERFIFO_H

View File

@@ -33,72 +33,73 @@
*/
#include "SchedulerFrFcfs.h"
#include "../../configuration/Configuration.h"
#include <systemc.h>
#include "BufferBankwise.h"
#include "BufferReadWrite.h"
using namespace tlm;
SchedulerFrFcfs::SchedulerFrFcfs()
{
buffer = std::vector<std::list<tlm_generic_payload *>>
(Configuration::getInstance().memSpec->numberOfBanks);
requestBufferSize = Configuration::getInstance().requestBufferSize;
Configuration &config = Configuration::getInstance();
localBuffer = std::vector<std::list<tlm_generic_payload *>>(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);
}

View File

@@ -38,24 +38,26 @@
#include <tlm.h>
#include <vector>
#include <list>
#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<std::list<tlm::tlm_generic_payload *>> buffer;
unsigned requestBufferSize;
unsigned lastBankID;
std::vector<std::list<tlm::tlm_generic_payload *>> localBuffer;
BufferIF *buffer;
};
#endif // SCHEDULERFRFCFS_H

View File

@@ -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<std::list<tlm_generic_payload *>>
(Configuration::getInstance().memSpec->numberOfBanks);
requestBufferSize = Configuration::getInstance().requestBufferSize;
Configuration &config = Configuration::getInstance();
localBuffer = std::vector<std::list<tlm_generic_payload *>>(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<tlm_generic_payload *> 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;

View File

@@ -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<std::list<tlm::tlm_generic_payload *>> buffer;
unsigned requestBufferSize;
std::vector<std::list<tlm::tlm_generic_payload *>> localBuffer;
tlm::tlm_command lastCommand = tlm::TLM_READ_COMMAND;
unsigned lastBankID;
BufferIF *buffer;
};
#endif // SCHEDULERFRFCFSGRP_H

View File

@@ -36,6 +36,7 @@
#define SCHEDULERIF_H
#include <tlm.h>
#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

View File

@@ -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 <random>
@@ -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(

View File

@@ -40,7 +40,7 @@
#include <iostream>
#include <systemc.h>
#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

View File

@@ -39,7 +39,7 @@
#include <bitset>
#include "AddressDecoder.h"
#include "utils.h"
#include "../common/utils.h"
#include "../configuration/Configuration.h"
using json = nlohmann::json;

View File

@@ -36,7 +36,7 @@
*/
#include "Arbiter.h"
#include "../common/AddressDecoder.h"
#include "AddressDecoder.h"
#include "../configuration/Configuration.h"
using namespace tlm;

View File

@@ -47,7 +47,7 @@
#include <tlm_utils/multi_passthrough_target_socket.h>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
#include <tlm_utils/peq_with_cb_and_phase.h>
#include "../common/AddressDecoder.h"
#include "AddressDecoder.h"
#include "../common/dramExtensions.h"
class Arbiter : public sc_module

View File

@@ -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);

View File

@@ -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<DramDDR3>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "DDR4")
else if (memoryType == MemSpec::MemoryType::DDR4)
dram = new DramRecordable<DramDDR4>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "DDR5")
else if (memoryType == MemSpec::MemoryType::DDR5)
dram = new DramRecordable<DramDDR5>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "LPDDR4")
dram = new DramRecordable<DramLPDDR4>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "WIDEIO_SDR")
else if (memoryType == MemSpec::MemoryType::WideIO)
dram = new DramRecordable<DramWideIO>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "WIDEIO2")
else if (memoryType == MemSpec::MemoryType::LPDDR4)
dram = new DramRecordable<DramLPDDR4>(str.c_str(), tlmRecorders[i]);
else if (memoryType == MemSpec::MemoryType::WideIO2)
dram = new DramRecordable<DramWideIO2>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "HBM2")
else if (memoryType == MemSpec::MemoryType::HBM2)
dram = new DramRecordable<DramHBM2>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "GDDR5")
else if (memoryType == MemSpec::MemoryType::GDDR5)
dram = new DramRecordable<DramGDDR5>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "GDDR5X")
else if (memoryType == MemSpec::MemoryType::GDDR5X)
dram = new DramRecordable<DramGDDR5X>(str.c_str(), tlmRecorders[i]);
else if (memoryType == "GDDR6")
else if (memoryType == MemSpec::MemoryType::GDDR6)
dram = new DramRecordable<DramGDDR6>(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);

View File

@@ -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());

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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();

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;