Moved memspec parsing into constructors.
This commit is contained in:
@@ -50,10 +50,19 @@
|
||||
class DebugManager
|
||||
{
|
||||
public:
|
||||
static DebugManager &getInstance()
|
||||
{
|
||||
static DebugManager _instance;
|
||||
return _instance;
|
||||
}
|
||||
~DebugManager();
|
||||
|
||||
DEF_SINGLETON(DebugManager);
|
||||
private:
|
||||
DebugManager();
|
||||
DebugManager(const DebugManager &);
|
||||
DebugManager & operator = (const DebugManager &);
|
||||
|
||||
public:
|
||||
bool writeToConsole;
|
||||
bool writeToFile;
|
||||
|
||||
@@ -62,9 +71,6 @@ public:
|
||||
void openDebugFile(std::string filename);
|
||||
|
||||
private:
|
||||
DebugManager();
|
||||
DebugManager(const DebugManager &) {}
|
||||
|
||||
ofstream debugFile;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <sstream>
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
bool TimeInterval::timeIsInInterval(sc_time time)
|
||||
{
|
||||
@@ -64,15 +65,15 @@ sc_time getDistance(sc_time a, sc_time b)
|
||||
return b - a;
|
||||
}
|
||||
|
||||
nlohmann::json parseJSON(std::string path)
|
||||
json parseJSON(std::string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
// parsing input with a syntax error
|
||||
nlohmann::json j = nlohmann::json::parse(std::ifstream(path));
|
||||
json j = json::parse(std::ifstream(path));
|
||||
return j;
|
||||
}
|
||||
catch (nlohmann::json::parse_error& e)
|
||||
catch (json::parse_error& e)
|
||||
{
|
||||
// output exception information
|
||||
std::cout << "Error while trying to parse file: " << path << '\n'
|
||||
@@ -80,6 +81,45 @@ nlohmann::json parseJSON(std::string path)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int parseUint(json &obj, std::string name)
|
||||
{
|
||||
if (!obj.empty())
|
||||
{
|
||||
if (obj.is_number_unsigned())
|
||||
return obj;
|
||||
else
|
||||
throw std::invalid_argument("Expected type for '" + name + "': unsigned int");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str());
|
||||
}
|
||||
|
||||
double parseUdouble(json &obj, std::string name)
|
||||
{
|
||||
if (!obj.empty())
|
||||
{
|
||||
if (obj.is_number() && (obj > 0))
|
||||
return obj;
|
||||
else
|
||||
throw std::invalid_argument("Expected type for '" + name + "': positive double");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str());
|
||||
}
|
||||
|
||||
std::string parseString(json &obj, std::string name)
|
||||
{
|
||||
if (!obj.empty())
|
||||
{
|
||||
if (obj.is_string())
|
||||
return obj;
|
||||
else
|
||||
throw std::invalid_argument("Expected type for '" + name + "': string");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str());
|
||||
}
|
||||
|
||||
void setUpDummy(tlm_generic_payload &payload, Rank rank, Bank bank)
|
||||
{
|
||||
payload.set_address(bank.getStartAddress());
|
||||
|
||||
@@ -50,14 +50,6 @@
|
||||
#include <sstream>
|
||||
#include "../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
#define DEF_SINGLETON( NAME ) \
|
||||
public: \
|
||||
static NAME& getInstance() \
|
||||
{ \
|
||||
static NAME _instance; \
|
||||
return _instance; \
|
||||
}
|
||||
|
||||
//TODO : move to timing specific header
|
||||
sc_time getDistance(sc_time a, sc_time b);
|
||||
|
||||
@@ -135,6 +127,9 @@ static inline void loadbar(unsigned int x,
|
||||
}
|
||||
|
||||
nlohmann::json parseJSON(std::string path);
|
||||
unsigned int parseUint(nlohmann::json &obj, std::string name);
|
||||
double parseUdouble(nlohmann::json &obj, std::string name);
|
||||
std::string parseString(nlohmann::json &obj, std::string name);
|
||||
|
||||
void setUpDummy(tlm::tlm_generic_payload &payload, Rank rank = Rank(0), Bank bank = Bank(0));
|
||||
|
||||
|
||||
@@ -50,16 +50,24 @@
|
||||
|
||||
#include "../error/eccbaseclass.h"
|
||||
|
||||
enum class StorageMode {NoStorage, Store, ErrorModel};
|
||||
|
||||
struct Configuration
|
||||
class Configuration
|
||||
{
|
||||
public:
|
||||
static Configuration &getInstance()
|
||||
{
|
||||
static Configuration _instance;
|
||||
return _instance;
|
||||
}
|
||||
private:
|
||||
Configuration() {}
|
||||
Configuration(const Configuration &);
|
||||
Configuration & operator = (const Configuration &);
|
||||
|
||||
public:
|
||||
static std::string memspecUri;
|
||||
static std::string mcconfigUri;
|
||||
std::string pathToResources;
|
||||
|
||||
DEF_SINGLETON(Configuration);
|
||||
|
||||
// MCConfig:
|
||||
std::string pagePolicy = "Open";
|
||||
std::string scheduler = "Fifo";
|
||||
@@ -72,6 +80,7 @@ struct Configuration
|
||||
unsigned int refreshMaxPulledin = 0;
|
||||
std::string powerDownPolicy = "NoPowerDown";
|
||||
unsigned int powerDownTimeout = 3;
|
||||
|
||||
// SimConfig
|
||||
std::string simulationName = "default";
|
||||
bool databaseRecording = false;
|
||||
|
||||
@@ -71,666 +71,23 @@ void ConfigurationLoader::loadMemSpec(Configuration &config, std::string memspec
|
||||
std::string memoryType = memspec["memoryType"];
|
||||
|
||||
if (memoryType == "DDR3")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecDDR3();
|
||||
loadCommons(config, memspec);
|
||||
loadDDR3(config, memspec);
|
||||
}
|
||||
Configuration::getInstance().memSpec = new MemSpecDDR3(memspec);
|
||||
else if (memoryType == "DDR4")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecDDR4();
|
||||
loadCommons(config, memspec);
|
||||
loadDDR4(config, memspec);
|
||||
}
|
||||
Configuration::getInstance().memSpec = new MemSpecDDR4(memspec);
|
||||
else if (memoryType == "LPDDR4")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecLPDDR4();
|
||||
loadCommons(config, memspec);
|
||||
loadLPDDR4(config, memspec);
|
||||
}
|
||||
Configuration::getInstance().memSpec = new MemSpecLPDDR4(memspec);
|
||||
else if (memoryType == "WIDEIO_SDR")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecWideIO();
|
||||
loadCommons(config, memspec);
|
||||
loadWideIO(config, memspec);
|
||||
}
|
||||
Configuration::getInstance().memSpec = new MemSpecWideIO(memspec);
|
||||
else if (memoryType == "WIDEIO2")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecWideIO2();
|
||||
loadCommons(config, memspec);
|
||||
loadWideIO2(config, memspec);
|
||||
}
|
||||
Configuration::getInstance().memSpec = new MemSpecWideIO2(memspec);
|
||||
else if (memoryType == "HBM2")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecHBM2();
|
||||
loadCommons(config, memspec);
|
||||
loadHBM2(config, memspec);
|
||||
}
|
||||
Configuration::getInstance().memSpec = new MemSpecHBM2(memspec);
|
||||
else if (memoryType == "GDDR5")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecGDDR5();
|
||||
loadCommons(config, memspec);
|
||||
loadGDDR5(config, memspec);
|
||||
}
|
||||
Configuration::getInstance().memSpec = new MemSpecGDDR5(memspec);
|
||||
else if (memoryType == "GDDR5X")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecGDDR5X();
|
||||
loadCommons(config, memspec);
|
||||
loadGDDR5X(config, memspec);
|
||||
}
|
||||
Configuration::getInstance().memSpec = new MemSpecGDDR5X(memspec);
|
||||
else if (memoryType == "GDDR6")
|
||||
{
|
||||
Configuration::getInstance().memSpec = new MemSpecGDDR6();
|
||||
loadCommons(config, memspec);
|
||||
loadGDDR6(config, memspec);
|
||||
}
|
||||
Configuration::getInstance().memSpec = new MemSpecGDDR6(memspec);
|
||||
else
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Unsupported DRAM type");
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadCommons(Configuration &config, json &memspec)
|
||||
{
|
||||
MemSpec *memSpec = config.memSpec;
|
||||
memSpec->memoryId = parseString(memspec["memoryId"], "memoryId");
|
||||
memSpec->memoryType = parseString(memspec["memoryType"], "memoryType");
|
||||
|
||||
// MemArchitecture
|
||||
memSpec->burstLength = parseUint(memspec["memarchitecturespec"]["burstLength"],"burstLength");
|
||||
memSpec->dataRate = parseUint(memspec["memarchitecturespec"]["dataRate"],"dataRate");
|
||||
memSpec->numberOfRows = parseUint(memspec["memarchitecturespec"]["nbrOfRows"],"nbrOfRows");
|
||||
memSpec->numberOfColumns = parseUint(memspec["memarchitecturespec"]["nbrOfColumns"],"nbrOfColumns");
|
||||
memSpec->bitWidth = parseUint(memspec["memarchitecturespec"]["width"],"width");
|
||||
|
||||
// Clock
|
||||
memSpec->fCKMHz = parseUdouble(memspec["memtimingspec"]["clkMhz"], "clkMhz");
|
||||
memSpec->tCK = sc_time(1.0 / memSpec->fCKMHz, SC_US);
|
||||
|
||||
memSpec->burstDuration = memSpec->tCK * (memSpec->burstLength / memSpec->dataRate);
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadDDR3(Configuration &config, json &memspec)
|
||||
{
|
||||
MemSpecDDR3 *memSpec = dynamic_cast<MemSpecDDR3 *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
||||
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
memSpec->numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"],"nbrOfRanks");
|
||||
memSpec->banksPerRank = parseUint(memspec[arch]["nbrOfBanks"],"nbrOfBanks");
|
||||
memSpec->groupsPerRank = 1;
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for DDR3
|
||||
std::string timings = "memtimingspec";
|
||||
memSpec->tCKE = memSpec->tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
memSpec->tPD = memSpec->tCKE;
|
||||
memSpec->tCKESR = memSpec->tCK * parseUint(memspec[timings]["CKESR"], "CKESR");
|
||||
memSpec->tCKE = memSpec->tCK * parseUint(memspec[timings]["DQSCK"], "DQSCK");
|
||||
memSpec->tRAS = memSpec->tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
memSpec->tRC = memSpec->tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
memSpec->tRCD = memSpec->tCK * parseUint(memspec[timings]["RCD"], "RCD");
|
||||
memSpec->tRL = memSpec->tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
memSpec->tRTP = memSpec->tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
memSpec->tWL = memSpec->tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
memSpec->tWR = memSpec->tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
memSpec->tXP = memSpec->tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
memSpec->tXS = memSpec->tCK * parseUint(memspec[timings]["XS"], "XS");
|
||||
memSpec->tCCD = memSpec->tCK * parseUint(memspec[timings]["CCD"], "CCD");
|
||||
memSpec->tFAW = memSpec->tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
memSpec->tREFI = memSpec->tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
memSpec->tRFC = memSpec->tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
memSpec->tRP = memSpec->tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
memSpec->tRRD = memSpec->tCK * parseUint(memspec[timings]["RRD"], "RRD");
|
||||
memSpec->tWTR = memSpec->tCK * parseUint(memspec[timings]["WTR"], "WTR");
|
||||
memSpec->tAL = memSpec->tCK * parseUint(memspec[timings]["AL"], "AL");
|
||||
memSpec->tXPDLL = memSpec->tCK * parseUint(memspec[timings]["XPDLL"], "XPDLL");
|
||||
memSpec->tXSDLL = memSpec->tCK * parseUint(memspec[timings]["XSDLL"], "XSDLL");
|
||||
memSpec->tACTPDEN = memSpec->tCK * parseUint(memspec[timings]["ACTPDEN"], "ACTPDEN");
|
||||
memSpec->tPRPDEN = memSpec->tCK * parseUint(memspec[timings]["PRPDEN"], "PRPDEN");
|
||||
memSpec->tREFPDEN = memSpec->tCK * parseUint(memspec[timings]["REFPDEN"], "REFPDEN");
|
||||
memSpec->tRTRS = memSpec->tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
std::string power = "mempowerspec";
|
||||
memSpec->iDD0 = parseUdouble(memspec[power]["idd0"], "idd0");
|
||||
memSpec->iDD2N = parseUdouble(memspec[power]["idd2n"], "idd2n");
|
||||
memSpec->iDD3N = parseUdouble(memspec[power]["idd3n"], "idd3n");
|
||||
memSpec->iDD4R = parseUdouble(memspec[power]["idd4r"], "idd4r");
|
||||
memSpec->iDD4W = parseUdouble(memspec[power]["idd4w"], "idd4w");
|
||||
memSpec->iDD5 = parseUdouble(memspec[power]["idd5"], "idd5");
|
||||
memSpec->iDD6 = parseUdouble(memspec[power]["idd6"], "idd6");
|
||||
memSpec->vDD = parseUdouble(memspec[power]["vdd"], "vdd");
|
||||
memSpec->iDD2P0 = parseUdouble(memspec[power]["idd2p0"], "idd2p0");
|
||||
memSpec->iDD2P1 = parseUdouble(memspec[power]["idd2p1"], "idd2p1");
|
||||
memSpec->iDD3P0 = parseUdouble(memspec[power]["idd3p0"], "idd3p0");
|
||||
memSpec->iDD3P1 = parseUdouble(memspec[power]["idd3p1"], "idd3p1");
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadDDR4(Configuration &config, json &memspec)
|
||||
{
|
||||
MemSpecDDR4 *memSpec = dynamic_cast<MemSpecDDR4 *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
||||
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
memSpec->numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"],"nbrOfRanks");
|
||||
memSpec->banksPerRank = parseUint(memspec[arch]["nbrOfBanks"],"nbrOfBanks");
|
||||
memSpec->groupsPerRank = parseUint(memspec[arch]["nbrOfBankGroups"], "nbrOfBankGroups");
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for DDR4
|
||||
std::string timings = "memtimingspec";
|
||||
memSpec->tCKE = memSpec->tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
memSpec->tPD = memSpec->tCKE;
|
||||
memSpec->tCKESR = memSpec->tCK * parseUint(memspec[timings]["CKESR"], "CKESR");
|
||||
memSpec->tDQSCK = memSpec->tCK * parseUint(memspec[timings]["DQSCK"], "DQSCK");
|
||||
memSpec->tRAS = memSpec->tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
memSpec->tRC = memSpec->tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
memSpec->tRCD = memSpec->tCK * parseUint(memspec[timings]["RCD"], "RCD");
|
||||
memSpec->tRL = memSpec->tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
memSpec->tRTP = memSpec->tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
memSpec->tWL = memSpec->tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
memSpec->tWR = memSpec->tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
memSpec->tXP = memSpec->tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
memSpec->tXS = memSpec->tCK * parseUint(memspec[timings]["XS"], "XS");
|
||||
memSpec->tCCD_S = memSpec->tCK * parseUint(memspec[timings]["CCD_S"], "CCD_S");
|
||||
memSpec->tCCD_L = memSpec->tCK * parseUint(memspec[timings]["CCD_L"], "CCD_L");
|
||||
memSpec->tFAW = memSpec->tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
|
||||
unsigned refreshMode = Configuration::getInstance().refreshMode;
|
||||
if (refreshMode == 1)
|
||||
{
|
||||
memSpec->tREFI = memSpec->tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
memSpec->tRFC = memSpec->tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
}
|
||||
else if (refreshMode == 2)
|
||||
{
|
||||
memSpec->tREFI = memSpec->tCK * (parseUint(memspec[timings]["REFI"], "REFI") / 2);
|
||||
memSpec->tRFC = memSpec->tCK * parseUint(memspec[timings]["RFC2"], "RFC2");
|
||||
}
|
||||
else if (refreshMode == 4)
|
||||
{
|
||||
memSpec->tREFI = memSpec->tCK * (parseUint(memspec[timings]["REFI"], "REFI") / 2);
|
||||
memSpec->tRFC = memSpec->tCK * parseUint(memspec[timings]["RFC4"], "RFC4");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Refresh Mode not supported");
|
||||
|
||||
memSpec->tRP = memSpec->tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
memSpec->tRRD_S = memSpec->tCK * parseUint(memspec[timings]["RRD_S"], "RRD_S");
|
||||
memSpec->tRRD_L = memSpec->tCK * parseUint(memspec[timings]["RRD_L"], "RRD_L");
|
||||
memSpec->tWTR_S = memSpec->tCK * parseUint(memspec[timings]["WTR_S"], "WTR_S");
|
||||
memSpec->tWTR_L = memSpec->tCK * parseUint(memspec[timings]["WTR_L"], "WTR_L");
|
||||
memSpec->tAL = memSpec->tCK * parseUint(memspec[timings]["AL"], "AL");
|
||||
memSpec->tXPDLL = memSpec->tCK * parseUint(memspec[timings]["XPDLL"], "XPDLL");
|
||||
memSpec->tXSDLL = memSpec->tCK * parseUint(memspec[timings]["XSDLL"], "XSDLL");
|
||||
memSpec->tACTPDEN = memSpec->tCK * parseUint(memspec[timings]["ACTPDEN"], "ACTPDEN");
|
||||
memSpec->tPRPDEN = memSpec->tCK * parseUint(memspec[timings]["PRPDEN"], "PRPDEN");
|
||||
memSpec->tREFPDEN = memSpec->tCK * parseUint(memspec[timings]["REFPDEN"], "REFPDEN");
|
||||
memSpec->tRTRS = memSpec->tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
std::string power = "mempowerspec";
|
||||
memSpec->iDD0 = parseUdouble(memspec[power]["idd0"], "idd0");
|
||||
memSpec->iDD2N = parseUdouble(memspec[power]["idd2n"], "idd2n");
|
||||
memSpec->iDD3N = parseUdouble(memspec[power]["idd3n"], "idd3n");
|
||||
memSpec->iDD4R = parseUdouble(memspec[power]["idd4r"], "idd4r");
|
||||
memSpec->iDD4W = parseUdouble(memspec[power]["idd4w"], "idd4w");
|
||||
memSpec->iDD5 = parseUdouble(memspec[power]["idd5"], "idd5");
|
||||
memSpec->iDD6 = parseUdouble(memspec[power]["idd6"], "idd6");
|
||||
memSpec->vDD = parseUdouble(memspec[power]["vdd"], "vdd");
|
||||
memSpec->iDD02 = parseUdouble(memspec[power]["idd02"], "idd02");
|
||||
memSpec->iDD2P0 = parseUdouble(memspec[power]["idd2p0"], "idd2p0");
|
||||
memSpec->iDD2P1 = parseUdouble(memspec[power]["idd2p1"], "idd2p1");
|
||||
memSpec->iDD3P0 = parseUdouble(memspec[power]["idd3p0"], "idd3p0");
|
||||
memSpec->iDD3P1 = parseUdouble(memspec[power]["idd3p1"], "idd3p1");
|
||||
memSpec->iDD62 = parseUdouble(memspec[power]["idd62"], "idd62");
|
||||
memSpec->vDD2 = parseUdouble(memspec[power]["vdd2"], "vdd2");
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadLPDDR4(Configuration &config, json &memspec)
|
||||
{
|
||||
MemSpecLPDDR4 *memSpec = dynamic_cast<MemSpecLPDDR4 *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
||||
|
||||
// MemArchitecture:
|
||||
std::string arch = "memarchitecturespec";
|
||||
memSpec->numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"],"nbrOfRanks");
|
||||
memSpec->banksPerRank = parseUint(memspec[arch]["nbrOfBanks"],"nbrOfBanks");
|
||||
memSpec->groupsPerRank = 1;
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for LPDDR4
|
||||
std::string timings = "memtimingspec";
|
||||
memSpec->tREFI = memSpec->tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
memSpec->tREFIpb = memSpec->tCK * parseUint(memspec[timings]["REFIPB"], "REFIPB");
|
||||
memSpec->tRFCab = memSpec->tCK * parseUint(memspec[timings]["RFCAB"], "RFCAB");
|
||||
memSpec->tRFCpb = memSpec->tCK * parseUint(memspec[timings]["RFCPB"], "RFCPB");
|
||||
memSpec->tRPab = memSpec->tCK * parseUint(memspec[timings]["RPAB"], "RPAB");
|
||||
memSpec->tRPpb = memSpec->tCK * parseUint(memspec[timings]["RPPB"], "RPPB");
|
||||
memSpec->tRCab = memSpec->tCK * parseUint(memspec[timings]["RCAB"], "RCAB");
|
||||
memSpec->tRCpb = memSpec->tCK * parseUint(memspec[timings]["RCPB"], "RCPB");
|
||||
memSpec->tPPD = memSpec->tCK * parseUint(memspec[timings]["PPD"], "PPD");
|
||||
memSpec->tRAS = memSpec->tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
memSpec->tRCD = memSpec->tCK * parseUint(memspec[timings]["RCD"], "RCD");
|
||||
memSpec->tFAW = memSpec->tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
memSpec->tRRD = memSpec->tCK * parseUint(memspec[timings]["RRD"], "RRD");
|
||||
memSpec->tCCD = memSpec->tCK * parseUint(memspec[timings]["CCD"], "CCD");
|
||||
memSpec->tRL = memSpec->tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
memSpec->tRPST = memSpec->tCK * parseUint(memspec[timings]["RPST"], "RPST");
|
||||
memSpec->tDQSCK = memSpec->tCK * parseUint(memspec[timings]["DQSCK"], "DQSCK");
|
||||
memSpec->tRTP = memSpec->tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
memSpec->tWL = memSpec->tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
memSpec->tDQSS = memSpec->tCK * parseUint(memspec[timings]["DQSS"], "DQSS");
|
||||
memSpec->tDQS2DQ = memSpec->tCK * parseUint(memspec[timings]["DQS2DQ"], "DQS2DQ");
|
||||
memSpec->tWR = memSpec->tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
memSpec->tWPRE = memSpec->tCK * parseUint(memspec[timings]["WPRE"], "WPRE");
|
||||
memSpec->tWTR = memSpec->tCK * parseUint(memspec[timings]["WTR"], "WTR");
|
||||
memSpec->tXP = memSpec->tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
memSpec->tSR = memSpec->tCK * parseUint(memspec[timings]["SR"], "SR");
|
||||
memSpec->tXSR = memSpec->tCK * parseUint(memspec[timings]["XSR"], "XSR");
|
||||
memSpec->tESCKE = memSpec->tCK * parseUint(memspec[timings]["ESCKE"], "ESCKE");
|
||||
memSpec->tCKE = memSpec->tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
memSpec->tCMDCKE = memSpec->tCK * parseUint(memspec[timings]["CMDCKE"], "CMDCKE");
|
||||
memSpec->tRTRS = memSpec->tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadWideIO(Configuration &config, json &memspec)
|
||||
{
|
||||
MemSpecWideIO *memSpec = dynamic_cast<MemSpecWideIO *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
||||
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
memSpec->numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"], "nbrOfRanks");
|
||||
memSpec->banksPerRank = parseUint(memspec[arch]["nbrOfBanks"], "nbrOfBanks");
|
||||
memSpec->groupsPerRank = 1;
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for WideIO
|
||||
std::string timings = "memtimingspec";
|
||||
memSpec->tCKE = memSpec->tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
memSpec->tCKESR = memSpec->tCK * parseUint(memspec[timings]["CKESR"], "CKESR");
|
||||
memSpec->tDQSCK = memSpec->tCK * parseUint(memspec[timings]["DQSCK"], "DQSCK");
|
||||
memSpec->tAC = memSpec->tCK * parseUint(memspec[timings]["AC"], "AC");
|
||||
memSpec->tRAS = memSpec->tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
memSpec->tRC = memSpec->tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
memSpec->tRCD = memSpec->tCK * parseUint(memspec[timings]["RCD"], "RCD");
|
||||
memSpec->tRL = memSpec->tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
memSpec->tWL = memSpec->tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
memSpec->tWR = memSpec->tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
memSpec->tXP = memSpec->tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
memSpec->tXSR = memSpec->tCK * parseUint(memspec[timings]["XSR"], "XSR");
|
||||
memSpec->tCCD_R = memSpec->tCK * parseUint(memspec[timings]["CCD_R"], "CCD_R");
|
||||
memSpec->tCCD_W = memSpec->tCK * parseUint(memspec[timings]["CCD_W"], "CCD_W");
|
||||
memSpec->tREFI = memSpec->tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
memSpec->tRFC = memSpec->tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
memSpec->tRP = memSpec->tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
memSpec->tRRD = memSpec->tCK * parseUint(memspec[timings]["RRD"], "RRD");
|
||||
memSpec->tTAW = memSpec->tCK * parseUint(memspec[timings]["TAW"], "TAW");
|
||||
memSpec->tWTR = memSpec->tCK * parseUint(memspec[timings]["WTR"], "WTR");
|
||||
memSpec->tRTRS = memSpec->tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
std::string power = "mempowerspec";
|
||||
memSpec->iDD0 = parseUdouble(memspec[power]["idd0"], "idd0");
|
||||
memSpec->iDD2N = parseUdouble(memspec[power]["idd2n"], "idd2n");
|
||||
memSpec->iDD3N = parseUdouble(memspec[power]["idd3n"], "idd3n");
|
||||
memSpec->iDD4R = parseUdouble(memspec[power]["idd4r"], "idd4r");
|
||||
memSpec->iDD4W = parseUdouble(memspec[power]["idd4w"], "idd4w");
|
||||
memSpec->iDD5 = parseUdouble(memspec[power]["idd5"], "idd5");
|
||||
memSpec->iDD6 = parseUdouble(memspec[power]["idd6"], "idd6");
|
||||
memSpec->vDD = parseUdouble(memspec[power]["vdd"], "vdd");
|
||||
memSpec->iDD02 = parseUdouble(memspec[power]["idd02"], "idd02");
|
||||
memSpec->iDD2P0 = parseUdouble(memspec[power]["idd2p0"], "idd2p0");
|
||||
memSpec->iDD2P02 = parseUdouble(memspec[power]["idd2p02"], "idd2p02");
|
||||
memSpec->iDD2P1 = parseUdouble(memspec[power]["idd2p1"], "idd2p1");
|
||||
memSpec->iDD2P12 = parseUdouble(memspec[power]["idd2p12"], "idd2p12");
|
||||
memSpec->iDD2N2 = parseUdouble(memspec[power]["idd2n2"], "idd2n2");
|
||||
memSpec->iDD3P0 = parseUdouble(memspec[power]["idd3p0"], "idd3p0");
|
||||
memSpec->iDD3P02 = parseUdouble(memspec[power]["idd3p02"], "idd3p02");
|
||||
memSpec->iDD3P1 = parseUdouble(memspec[power]["idd3p1"], "idd3p1");
|
||||
memSpec->iDD3P12 = parseUdouble(memspec[power]["idd3p12"], "idd3p12");
|
||||
memSpec->iDD3N2 = parseUdouble(memspec[power]["idd3n2"], "idd3n2");
|
||||
memSpec->iDD4R2 = parseUdouble(memspec[power]["idd4r2"], "idd4r2");
|
||||
memSpec->iDD4W2 = parseUdouble(memspec[power]["idd4w2"], "idd4w2");
|
||||
memSpec->iDD52 = parseUdouble(memspec[power]["idd52"], "idd52");
|
||||
memSpec->iDD62 = parseUdouble(memspec[power]["idd62"], "idd62");
|
||||
memSpec->vDD2 = parseUdouble(memspec[power]["vdd2"], "vdd2");
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadWideIO2(Configuration &config, json &memspec)
|
||||
{
|
||||
MemSpecWideIO2 *memSpec = dynamic_cast<MemSpecWideIO2 *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
||||
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
memSpec->numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"], "nbrOfRanks");
|
||||
memSpec->banksPerRank = parseUint(memspec[arch]["nbrOfBanks"], "nbrOfBanks");
|
||||
memSpec->groupsPerRank = 1;
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for WideIO2
|
||||
std::string timings = "memtimingspec";
|
||||
memSpec->tDQSCK = memSpec->tCK * parseUint(memspec[timings]["DQSCK"], "DQSCK");
|
||||
memSpec->tDQSS = memSpec->tCK * parseUint(memspec[timings]["DQSS"], "DQSS");
|
||||
memSpec->tCKE = memSpec->tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
memSpec->tRL = memSpec->tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
memSpec->tWL = memSpec->tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
memSpec->tRCpb = memSpec->tCK * parseUint(memspec[timings]["RCPB"], "RCPB");
|
||||
memSpec->tRCab = memSpec->tCK * parseUint(memspec[timings]["RCAB"], "RCAB");
|
||||
memSpec->tCKESR = memSpec->tCK * parseUint(memspec[timings]["CKESR"], "CKESR");
|
||||
memSpec->tXSR = memSpec->tCK * parseUint(memspec[timings]["XSR"], "XSR");
|
||||
memSpec->tXP = memSpec->tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
memSpec->tCCD = memSpec->tCK * parseUint(memspec[timings]["CCD"], "CCD");
|
||||
memSpec->tRTP = memSpec->tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
memSpec->tRCD = memSpec->tCK * parseUint(memspec[timings]["RCD"], "RCD");
|
||||
memSpec->tRPpb = memSpec->tCK * parseUint(memspec[timings]["RPPB"], "RPPB");
|
||||
memSpec->tRPab = memSpec->tCK * parseUint(memspec[timings]["RPAB"], "RPAB");
|
||||
memSpec->tRAS = memSpec->tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
memSpec->tWR = memSpec->tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
memSpec->tWTR = memSpec->tCK * parseUint(memspec[timings]["WTR"], "WTR");
|
||||
memSpec->tRRD = memSpec->tCK * parseUint(memspec[timings]["RRD"], "RRD");
|
||||
memSpec->tFAW = memSpec->tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
memSpec->tREFI = memSpec->tCK * (unsigned)(parseUint(memspec[timings]["REFI"], "REFI")
|
||||
* parseUdouble(memspec[timings]["REFM"], "REFM"));
|
||||
memSpec->tREFIpb = memSpec->tCK * (unsigned)(parseUint(memspec[timings]["REFIPB"], "REFIPB")
|
||||
* parseUdouble(memspec[timings]["REFM"], "REFM"));
|
||||
memSpec->tRFCab = memSpec->tCK * parseUint(memspec[timings]["RFCAB"], "RFCAB");
|
||||
memSpec->tRFCpb = memSpec->tCK * parseUint(memspec[timings]["RFCPB"], "RFCPB");
|
||||
memSpec->tRTRS = memSpec->tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadHBM2(Configuration &config, json &memspec)
|
||||
{
|
||||
MemSpecHBM2 *memSpec = dynamic_cast<MemSpecHBM2 *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
||||
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
memSpec->numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"], "nbrOfRanks");
|
||||
memSpec->banksPerRank = parseUint(memspec[arch]["nbrOfBanks"], "nbrOfBanks");
|
||||
memSpec->groupsPerRank = parseUint(memspec[arch]["nbrOfBankGroups"], "nbrOfBankGroups");
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for HBM2
|
||||
std::string timings = "memtimingspec";
|
||||
memSpec->tDQSCK = memSpec->tCK * parseUint(memspec[timings]["DQSCK"], "DQSCK");
|
||||
memSpec->tRC = memSpec->tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
memSpec->tRAS = memSpec->tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
memSpec->tRCDRD = memSpec->tCK * parseUint(memspec[timings]["RCDRD"], "RCDRD");
|
||||
memSpec->tRCDWR = memSpec->tCK * parseUint(memspec[timings]["RCDWR"], "RCDWR");
|
||||
memSpec->tRRDL = memSpec->tCK * parseUint(memspec[timings]["RRDL"], "RRDL");
|
||||
memSpec->tRRDS = memSpec->tCK * parseUint(memspec[timings]["RRDS"], "RRDS");
|
||||
memSpec->tFAW = memSpec->tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
memSpec->tRTP = memSpec->tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
memSpec->tRP = memSpec->tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
memSpec->tRL = memSpec->tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
memSpec->tWL = memSpec->tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
memSpec->tPL = memSpec->tCK * parseUint(memspec[timings]["PL"], "PL");
|
||||
memSpec->tWR = memSpec->tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
memSpec->tCCDL = memSpec->tCK * parseUint(memspec[timings]["CCDL"], "CCDL");
|
||||
memSpec->tCCDS = memSpec->tCK * parseUint(memspec[timings]["CCDS"], "CCDS");
|
||||
memSpec->tWTRL = memSpec->tCK * parseUint(memspec[timings]["WTRL"], "WTRL");
|
||||
memSpec->tWTRS = memSpec->tCK * parseUint(memspec[timings]["WTRS"], "WTRS");
|
||||
memSpec->tRTW = memSpec->tCK * parseUint(memspec[timings]["RTW"], "RTW");
|
||||
memSpec->tXP = memSpec->tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
memSpec->tCKE = memSpec->tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
memSpec->tPD = memSpec->tCKE;
|
||||
memSpec->tCKESR = memSpec->tCKE + memSpec->tCK;
|
||||
memSpec->tXS = memSpec->tCK * parseUint(memspec[timings]["XS"], "XS");
|
||||
memSpec->tRFC = memSpec->tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
memSpec->tRFCSB = memSpec->tCK * parseUint(memspec[timings]["RFCSB"], "RFCSB");
|
||||
memSpec->tRREFD = memSpec->tCK * parseUint(memspec[timings]["RREFD"], "RREFD");
|
||||
memSpec->tREFI = memSpec->tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
memSpec->tREFISB = memSpec->tCK * parseUint(memspec[timings]["REFISB"], "REFISB");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadGDDR5(Configuration &config, json &memspec)
|
||||
{
|
||||
MemSpecGDDR5 *memSpec = dynamic_cast<MemSpecGDDR5 *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
||||
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
memSpec->numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"], "nbrOfRanks");
|
||||
memSpec->banksPerRank = parseUint(memspec[arch]["nbrOfBanks"], "nbrOfBanks");
|
||||
memSpec->groupsPerRank = parseUint(memspec[arch]["nbrOfBankGroups"], "nbrOfBankGroups");
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for GDDR5
|
||||
std::string timings = "memtimingspec";
|
||||
memSpec->tRP = memSpec->tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
memSpec->tRAS = memSpec->tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
memSpec->tRC = memSpec->tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
memSpec->tRCDRD = memSpec->tCK * parseUint(memspec[timings]["RCDRD"], "RCDRD");
|
||||
memSpec->tRCDWR = memSpec->tCK * parseUint(memspec[timings]["RCDWR"], "RCDWR");
|
||||
memSpec->tRTP = memSpec->tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
memSpec->tRRDS = memSpec->tCK * parseUint(memspec[timings]["RRDS"], "RRDS");
|
||||
memSpec->tRRDL = memSpec->tCK * parseUint(memspec[timings]["RRDL"], "RRDL");
|
||||
memSpec->tCCDS = memSpec->tCK * parseUint(memspec[timings]["CCDS"], "CCDS");
|
||||
memSpec->tCCDL = memSpec->tCK * parseUint(memspec[timings]["CCDL"], "CCDL");
|
||||
memSpec->tCL = memSpec->tCK * parseUint(memspec[timings]["CL"], "CL");
|
||||
memSpec->tWCK2CKPIN = memSpec->tCK * parseUint(memspec[timings]["WCK2CKPIN"], "WCK2CKPIN");
|
||||
memSpec->tWCK2CK = memSpec->tCK * parseUint(memspec[timings]["WCK2CK"], "WCK2CK");
|
||||
memSpec->tWCK2DQO = memSpec->tCK * parseUint(memspec[timings]["WCK2DQO"], "WCK2DQO");
|
||||
memSpec->tRTW = memSpec->tCK * parseUint(memspec[timings]["RTW"], "RTW");
|
||||
memSpec->tWL = memSpec->tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
memSpec->tWCK2DQI = memSpec->tCK * parseUint(memspec[timings]["WCK2DQI"], "WCK2DQI");
|
||||
memSpec->tWR = memSpec->tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
memSpec->tWTRS = memSpec->tCK * parseUint(memspec[timings]["WTRS"], "WTRS");
|
||||
memSpec->tWTRL = memSpec->tCK * parseUint(memspec[timings]["WTRL"], "WTRL");
|
||||
memSpec->tCKE = memSpec->tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
memSpec->tPD = memSpec->tCK * parseUint(memspec[timings]["PD"], "PD");
|
||||
memSpec->tXPN = memSpec->tCK * parseUint(memspec[timings]["XPN"], "XPN");
|
||||
memSpec->tREFI = memSpec->tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
memSpec->tREFIPB = memSpec->tCK * parseUint(memspec[timings]["REFIPB"], "REFIPB");
|
||||
memSpec->tRFC = memSpec->tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
memSpec->tRFCPB = memSpec->tCK * parseUint(memspec[timings]["RFCPB"], "RFCPB");
|
||||
memSpec->tRREFD = memSpec->tCK * parseUint(memspec[timings]["RREFD"], "RREFD");
|
||||
memSpec->tXS = memSpec->tCK * parseUint(memspec[timings]["XS"], "XS");
|
||||
memSpec->tFAW = memSpec->tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
memSpec->t32AW = memSpec->tCK * parseUint(memspec[timings]["32AW"], "32AW");
|
||||
// memSpec->tRDSRE = memSpec->tCL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
// + memSpec->tWCK2DQO + memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
// memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
// + memSpec->tWCK2DQI + memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
memSpec->tPPD = memSpec->tCK * parseUint(memspec[timings]["PPD"], "PPD");
|
||||
memSpec->tLK = memSpec->tCK * parseUint(memspec[timings]["LK"], "LK");
|
||||
memSpec->tRTRS = memSpec->tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadGDDR5X(Configuration &config, json &memspec)
|
||||
{
|
||||
MemSpecGDDR5X *memSpec = dynamic_cast<MemSpecGDDR5X *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
||||
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
memSpec->numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"], "nbrOfRanks");
|
||||
memSpec->banksPerRank = parseUint(memspec[arch]["nbrOfBanks"], "nbrOfBanks");
|
||||
memSpec->groupsPerRank = parseUint(memspec[arch]["nbrOfBankGroups"], "nbrOfBankGroups");
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for GDDR5X
|
||||
std::string timings = "memtimingspec";
|
||||
memSpec->tRP = memSpec->tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
memSpec->tRAS = memSpec->tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
memSpec->tRC = memSpec->tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
memSpec->tRCDRD = memSpec->tCK * parseUint(memspec[timings]["RCDRD"], "RCDRD");
|
||||
memSpec->tRCDWR = memSpec->tCK * parseUint(memspec[timings]["RCDWR"], "RCDWR");
|
||||
memSpec->tRTP = memSpec->tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
memSpec->tRRDS = memSpec->tCK * parseUint(memspec[timings]["RRDS"], "RRDS");
|
||||
memSpec->tRRDL = memSpec->tCK * parseUint(memspec[timings]["RRDL"], "RRDL");
|
||||
memSpec->tCCDS = memSpec->tCK * parseUint(memspec[timings]["CCDS"], "CCDS");
|
||||
memSpec->tCCDL = memSpec->tCK * parseUint(memspec[timings]["CCDL"], "CCDL");
|
||||
memSpec->tRL = memSpec->tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
memSpec->tWCK2CKPIN = memSpec->tCK * parseUint(memspec[timings]["WCK2CKPIN"], "WCK2CKPIN");
|
||||
memSpec->tWCK2CK = memSpec->tCK * parseUint(memspec[timings]["WCK2CK"], "WCK2CK");
|
||||
memSpec->tWCK2DQO = memSpec->tCK * parseUint(memspec[timings]["WCK2DQO"], "WCK2DQO");
|
||||
memSpec->tRTW = memSpec->tCK * parseUint(memspec[timings]["RTW"], "RTW");
|
||||
memSpec->tWL = memSpec->tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
memSpec->tWCK2DQI = memSpec->tCK * parseUint(memspec[timings]["WCK2DQI"], "WCK2DQI");
|
||||
memSpec->tWR = memSpec->tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
memSpec->tWTRS = memSpec->tCK * parseUint(memspec[timings]["WTRS"], "WTRS");
|
||||
memSpec->tWTRL = memSpec->tCK * parseUint(memspec[timings]["WTRL"], "WTRL");
|
||||
memSpec->tCKE = memSpec->tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
memSpec->tPD = memSpec->tCK * parseUint(memspec[timings]["PD"], "PD");
|
||||
memSpec->tXP = memSpec->tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
memSpec->tREFI = memSpec->tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
memSpec->tREFIPB = memSpec->tCK * parseUint(memspec[timings]["REFIPB"], "REFIPB");
|
||||
memSpec->tRFC = memSpec->tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
memSpec->tRFCPB = memSpec->tCK * parseUint(memspec[timings]["RFCPB"], "RFCPB");
|
||||
memSpec->tRREFD = memSpec->tCK * parseUint(memspec[timings]["RREFD"], "RREFD");
|
||||
memSpec->tXS = memSpec->tCK * parseUint(memspec[timings]["XS"], "XS");
|
||||
memSpec->tFAW = memSpec->tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
memSpec->t32AW = memSpec->tCK * parseUint(memspec[timings]["32AW"], "32AW");
|
||||
// memSpec->tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
// + memSpec->tWCK2DQO + memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
// memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
// + memSpec->tWCK2DQI + memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
memSpec->tPPD = memSpec->tCK * parseUint(memspec[timings]["PPD"], "PPD");
|
||||
memSpec->tLK = memSpec->tCK * parseUint(memspec[timings]["LK"], "LK");
|
||||
memSpec->tRTRS = memSpec->tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
void ConfigurationLoader::loadGDDR6(Configuration &config, json &memspec)
|
||||
{
|
||||
MemSpecGDDR6 *memSpec = dynamic_cast<MemSpecGDDR6 *>(config.memSpec);
|
||||
if (memSpec == nullptr)
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
||||
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
memSpec->numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"], "nbrOfRanks");
|
||||
memSpec->banksPerRank = parseUint(memspec[arch]["nbrOfBanks"], "nbrOfBanks");
|
||||
memSpec->groupsPerRank = parseUint(memspec[arch]["nbrOfBankGroups"], "nbrOfBankGroups");
|
||||
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
||||
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
||||
memSpec->numberOfBankGroups = memSpec->groupsPerRank * memSpec->numberOfRanks;
|
||||
|
||||
// MemTimings specific for GDDR6
|
||||
std::string timings = "memtimingspec";
|
||||
memSpec->tRP = memSpec->tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
memSpec->tRAS = memSpec->tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
memSpec->tRC = memSpec->tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
memSpec->tRCDRD = memSpec->tCK * parseUint(memspec[timings]["RCDRD"], "RCDRD");
|
||||
memSpec->tRCDWR = memSpec->tCK * parseUint(memspec[timings]["RCDWR"], "RCDWR");
|
||||
memSpec->tRTP = memSpec->tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
memSpec->tRRDS = memSpec->tCK * parseUint(memspec[timings]["RRDS"], "RRDS");
|
||||
memSpec->tRRDL = memSpec->tCK * parseUint(memspec[timings]["RRDL"], "RRDL");
|
||||
memSpec->tCCDS = memSpec->tCK * parseUint(memspec[timings]["CCDS"], "CCDS");
|
||||
memSpec->tCCDL = memSpec->tCK * parseUint(memspec[timings]["CCDL"], "CCDL");
|
||||
memSpec->tRL = memSpec->tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
memSpec->tWCK2CKPIN = memSpec->tCK * parseUint(memspec[timings]["WCK2CKPIN"], "WCK2CKPIN");
|
||||
memSpec->tWCK2CK = memSpec->tCK * parseUint(memspec[timings]["WCK2CK"], "WCK2CK");
|
||||
memSpec->tWCK2DQO = memSpec->tCK * parseUint(memspec[timings]["WCK2DQO"], "WCK2DQO");
|
||||
memSpec->tRTW = memSpec->tCK * parseUint(memspec[timings]["RTW"], "RTW");
|
||||
memSpec->tWL = memSpec->tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
memSpec->tWCK2DQI = memSpec->tCK * parseUint(memspec[timings]["WCK2DQI"], "WCK2DQI");
|
||||
memSpec->tWR = memSpec->tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
memSpec->tWTRS = memSpec->tCK * parseUint(memspec[timings]["WTRS"], "WTRS");
|
||||
memSpec->tWTRL = memSpec->tCK * parseUint(memspec[timings]["WTRL"], "WTRL");
|
||||
memSpec->tPD = memSpec->tCK * parseUint(memspec[timings]["PD"], "PD");
|
||||
memSpec->tCKESR = memSpec->tCK * parseUint(memspec[timings]["CKESR"], "CKESR");
|
||||
memSpec->tXP = memSpec->tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
memSpec->tREFI = memSpec->tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
memSpec->tREFIPB = memSpec->tCK * parseUint(memspec[timings]["REFIPB"], "REFIPB");
|
||||
memSpec->tRFC = memSpec->tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
memSpec->tRFCPB = memSpec->tCK * parseUint(memspec[timings]["RFCPB"], "RFCPB");
|
||||
memSpec->tRREFD = memSpec->tCK * parseUint(memspec[timings]["RREFD"], "RREFD");
|
||||
memSpec->tXS = memSpec->tCK * parseUint(memspec[timings]["XS"], "XS");
|
||||
memSpec->tFAW = memSpec->tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
// memSpec->tRDSRE = memSpec->tRL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
// + memSpec->tWCK2DQO + memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
// memSpec->tWRSRE = memSpec->tWL + memSpec->tWCK2CKPIN + memSpec->tWCK2CK
|
||||
// + memSpec->tWCK2DQI + memSpec->burstLength / memSpec->dataRate * memSpec->tCK;
|
||||
memSpec->tPPD = memSpec->tCK * parseUint(memspec[timings]["PPD"], "PPD");
|
||||
memSpec->tLK = memSpec->tCK * parseUint(memspec[timings]["LK"], "LK");
|
||||
memSpec->tACTPDE = memSpec->tCK * parseUint(memspec[timings]["ACTPDE"], "ACTPDE");
|
||||
memSpec->tPREPDE = memSpec->tCK * parseUint(memspec[timings]["PREPDE"], "PREPDE");
|
||||
memSpec->tREFPDE = memSpec->tCK * parseUint(memspec[timings]["REFPDE"], "REFPDE");
|
||||
memSpec->tRTRS = memSpec->tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
unsigned int ConfigurationLoader::parseUint(json &obj, std::string name)
|
||||
{
|
||||
if (!obj.empty())
|
||||
{
|
||||
if (obj.is_number_unsigned())
|
||||
return obj;
|
||||
else
|
||||
throw std::invalid_argument("Expected type for '" + name + "': unsigned int");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str());
|
||||
}
|
||||
|
||||
double ConfigurationLoader::parseUdouble(json &obj, std::string name)
|
||||
{
|
||||
if (!obj.empty())
|
||||
{
|
||||
if (obj.is_number() && (obj > 0))
|
||||
return obj;
|
||||
else
|
||||
throw std::invalid_argument("Expected type for '" + name + "': positive double");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str());
|
||||
}
|
||||
|
||||
std::string ConfigurationLoader::parseString(json &obj, std::string name)
|
||||
{
|
||||
if (!obj.empty())
|
||||
{
|
||||
if (obj.is_string())
|
||||
return obj;
|
||||
else
|
||||
throw std::invalid_argument("Expected type for '" + name + "': string");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("Query json", ("Parameter '" + name + "' does not exist.").c_str());
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#define CONFIGURATIONLOADER_H
|
||||
|
||||
#include <string>
|
||||
#include "../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
#include "../common/utils.h"
|
||||
#include "Configuration.h"
|
||||
#include "memspec/MemSpec.h"
|
||||
@@ -58,32 +57,12 @@ class ConfigurationLoader
|
||||
{
|
||||
public:
|
||||
static void loadMCConfig(Configuration &config, std::string amconfigUri);
|
||||
|
||||
static void loadSimConfig(Configuration &config, std::string simconfigUri);
|
||||
|
||||
static void loadMemSpec(Configuration &config, std::string memspecUri);
|
||||
static void loadTemperatureSimConfig(Configuration &config, std::string simconfigUri);
|
||||
|
||||
static void loadTemperatureSimConfig(Configuration &config,
|
||||
std::string simconfigUri);
|
||||
private:
|
||||
ConfigurationLoader() {}
|
||||
|
||||
// Loads common config of DRAMs
|
||||
static void loadCommons(Configuration &config, nlohmann::json &memspec);
|
||||
// Load specific config
|
||||
static void loadDDR3(Configuration &config, nlohmann::json &memspec);
|
||||
static void loadDDR4(Configuration &config, nlohmann::json &memspec);
|
||||
static void loadLPDDR4(Configuration &config, nlohmann::json &memspec);
|
||||
static void loadWideIO(Configuration &config, nlohmann::json &memspec);
|
||||
static void loadWideIO2(Configuration &config, nlohmann::json &memspec);
|
||||
static void loadHBM2(Configuration &config, nlohmann::json &memspec);
|
||||
static void loadGDDR5(Configuration &config, nlohmann::json &memspec);
|
||||
static void loadGDDR5X(Configuration &config, nlohmann::json &memspec);
|
||||
static void loadGDDR6(Configuration &config, nlohmann::json &memspec);
|
||||
|
||||
static unsigned int parseUint(nlohmann::json &obj, std::string name);
|
||||
static double parseUdouble(nlohmann::json &obj, std::string name);
|
||||
static std::string parseString(nlohmann::json &obj, std::string name);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -41,10 +41,27 @@
|
||||
#include "../Configuration.h"
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpec::MemSpec()
|
||||
MemSpec::MemSpec(json &memspec)
|
||||
{
|
||||
commandLengthInCycles = std::vector<unsigned>(numberOfCommands(), 1);
|
||||
|
||||
memoryId = parseString(memspec["memoryId"], "memoryId");
|
||||
memoryType = parseString(memspec["memoryType"], "memoryType");
|
||||
|
||||
// MemArchitecture
|
||||
burstLength = parseUint(memspec["memarchitecturespec"]["burstLength"],"burstLength");
|
||||
dataRate = parseUint(memspec["memarchitecturespec"]["dataRate"],"dataRate");
|
||||
numberOfRows = parseUint(memspec["memarchitecturespec"]["nbrOfRows"],"nbrOfRows");
|
||||
numberOfColumns = parseUint(memspec["memarchitecturespec"]["nbrOfColumns"],"nbrOfColumns");
|
||||
bitWidth = parseUint(memspec["memarchitecturespec"]["width"],"width");
|
||||
|
||||
// Clock
|
||||
fCKMHz = parseUdouble(memspec["memtimingspec"]["clkMhz"], "clkMhz");
|
||||
tCK = sc_time(1.0 / fCKMHz, SC_US);
|
||||
|
||||
burstDuration = tCK * (burstLength / dataRate);
|
||||
}
|
||||
|
||||
sc_time MemSpec::getCommandLength(Command command) const
|
||||
|
||||
@@ -43,10 +43,14 @@
|
||||
#include "../../common/dramExtensions.h"
|
||||
#include "../../controller/Command.h"
|
||||
#include "../../common/utils.h"
|
||||
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
struct MemSpec
|
||||
class MemSpec
|
||||
{
|
||||
MemSpec();
|
||||
protected:
|
||||
MemSpec(nlohmann::json &);
|
||||
|
||||
public:
|
||||
virtual ~MemSpec() {}
|
||||
|
||||
virtual sc_time getRefreshIntervalAB() const = 0;
|
||||
|
||||
@@ -36,6 +36,63 @@
|
||||
#include "MemSpecDDR3.h"
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecDDR3::MemSpecDDR3(json &memspec) : MemSpec(memspec)
|
||||
{
|
||||
std::string arch = "memarchitecturespec";
|
||||
numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"],"nbrOfRanks");
|
||||
banksPerRank = parseUint(memspec[arch]["nbrOfBanks"],"nbrOfBanks");
|
||||
groupsPerRank = 1;
|
||||
banksPerGroup = banksPerRank / groupsPerRank;
|
||||
numberOfBanks = banksPerRank * numberOfRanks;
|
||||
numberOfBankGroups = groupsPerRank * numberOfRanks;
|
||||
|
||||
// MemTimings specific for DDR3
|
||||
std::string timings = "memtimingspec";
|
||||
tCKE = tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
tPD = tCKE;
|
||||
tCKESR = tCK * parseUint(memspec[timings]["CKESR"], "CKESR");
|
||||
tCKE = tCK * parseUint(memspec[timings]["DQSCK"], "DQSCK");
|
||||
tRAS = tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
tRC = tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
tRCD = tCK * parseUint(memspec[timings]["RCD"], "RCD");
|
||||
tRL = tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
tRTP = tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
tWL = tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
tWR = tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
tXP = tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
tXS = tCK * parseUint(memspec[timings]["XS"], "XS");
|
||||
tCCD = tCK * parseUint(memspec[timings]["CCD"], "CCD");
|
||||
tFAW = tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
tREFI = tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
tRFC = tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
tRP = tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
tRRD = tCK * parseUint(memspec[timings]["RRD"], "RRD");
|
||||
tWTR = tCK * parseUint(memspec[timings]["WTR"], "WTR");
|
||||
tAL = tCK * parseUint(memspec[timings]["AL"], "AL");
|
||||
tXPDLL = tCK * parseUint(memspec[timings]["XPDLL"], "XPDLL");
|
||||
tXSDLL = tCK * parseUint(memspec[timings]["XSDLL"], "XSDLL");
|
||||
tACTPDEN = tCK * parseUint(memspec[timings]["ACTPDEN"], "ACTPDEN");
|
||||
tPRPDEN = tCK * parseUint(memspec[timings]["PRPDEN"], "PRPDEN");
|
||||
tREFPDEN = tCK * parseUint(memspec[timings]["REFPDEN"], "REFPDEN");
|
||||
tRTRS = tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
std::string power = "mempowerspec";
|
||||
iDD0 = parseUdouble(memspec[power]["idd0"], "idd0");
|
||||
iDD2N = parseUdouble(memspec[power]["idd2n"], "idd2n");
|
||||
iDD3N = parseUdouble(memspec[power]["idd3n"], "idd3n");
|
||||
iDD4R = parseUdouble(memspec[power]["idd4r"], "idd4r");
|
||||
iDD4W = parseUdouble(memspec[power]["idd4w"], "idd4w");
|
||||
iDD5 = parseUdouble(memspec[power]["idd5"], "idd5");
|
||||
iDD6 = parseUdouble(memspec[power]["idd6"], "idd6");
|
||||
vDD = parseUdouble(memspec[power]["vdd"], "vdd");
|
||||
iDD2P0 = parseUdouble(memspec[power]["idd2p0"], "idd2p0");
|
||||
iDD2P1 = parseUdouble(memspec[power]["idd2p1"], "idd2p1");
|
||||
iDD3P0 = parseUdouble(memspec[power]["idd3p0"], "idd3p0");
|
||||
iDD3P1 = parseUdouble(memspec[power]["idd3p1"], "idd3p1");
|
||||
}
|
||||
|
||||
sc_time MemSpecDDR3::getRefreshIntervalAB() const
|
||||
{
|
||||
|
||||
@@ -37,22 +37,26 @@
|
||||
#define MEMSPECDDR3_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
struct MemSpecDDR3 final : public MemSpec
|
||||
class MemSpecDDR3 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
MemSpecDDR3(nlohmann::json &);
|
||||
|
||||
// Memspec Variables:
|
||||
sc_time tCKE; // min time between pdx and pde
|
||||
sc_time tPD; // min time in pdn
|
||||
sc_time tCKESR; // min time in sref
|
||||
sc_time tRAS; // active-time (act -> pre same bank)
|
||||
sc_time tRC; // RAS-cycle-time (min time bw 2 succesive ACT to same bank)
|
||||
sc_time tRCD; // act -> read/write
|
||||
sc_time tRL; // read latency (read command start to data strobe)
|
||||
sc_time tRTP; // read to precharge
|
||||
sc_time tWL; // write latency
|
||||
sc_time tWR; // write recovery (write to precharge)
|
||||
sc_time tXP; // min delay to row access command after pdnpx pdnax
|
||||
sc_time tXS; // min delay to row access command after srefx
|
||||
sc_time tCKE;
|
||||
sc_time tPD;
|
||||
sc_time tCKESR;
|
||||
sc_time tRAS;
|
||||
sc_time tRC;
|
||||
sc_time tRCD;
|
||||
sc_time tRL;
|
||||
sc_time tRTP;
|
||||
sc_time tWL;
|
||||
sc_time tWR;
|
||||
sc_time tXP;
|
||||
sc_time tXS;
|
||||
sc_time tREFI;
|
||||
sc_time tRFC;
|
||||
sc_time tRP;
|
||||
|
||||
@@ -34,8 +34,90 @@
|
||||
*/
|
||||
|
||||
#include "MemSpecDDR4.h"
|
||||
#include "../Configuration.h"
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecDDR4::MemSpecDDR4(json &memspec) : MemSpec(memspec)
|
||||
{
|
||||
std::string arch = "memarchitecturespec";
|
||||
numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"],"nbrOfRanks");
|
||||
banksPerRank = parseUint(memspec[arch]["nbrOfBanks"],"nbrOfBanks");
|
||||
groupsPerRank = parseUint(memspec[arch]["nbrOfBankGroups"], "nbrOfBankGroups");
|
||||
banksPerGroup = banksPerRank / groupsPerRank;
|
||||
numberOfBanks = banksPerRank * numberOfRanks;
|
||||
numberOfBankGroups = groupsPerRank * numberOfRanks;
|
||||
|
||||
// MemTimings specific for DDR4
|
||||
std::string timings = "memtimingspec";
|
||||
tCKE = tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
tPD = tCKE;
|
||||
tCKESR = tCK * parseUint(memspec[timings]["CKESR"], "CKESR");
|
||||
tDQSCK = tCK * parseUint(memspec[timings]["DQSCK"], "DQSCK");
|
||||
tRAS = tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
tRC = tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
tRCD = tCK * parseUint(memspec[timings]["RCD"], "RCD");
|
||||
tRL = tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
tRTP = tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
tWL = tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
tWR = tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
tXP = tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
tXS = tCK * parseUint(memspec[timings]["XS"], "XS");
|
||||
tCCD_S = tCK * parseUint(memspec[timings]["CCD_S"], "CCD_S");
|
||||
tCCD_L = tCK * parseUint(memspec[timings]["CCD_L"], "CCD_L");
|
||||
tFAW = tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
|
||||
unsigned refreshMode = Configuration::getInstance().refreshMode;
|
||||
if (refreshMode == 1)
|
||||
{
|
||||
tREFI = tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
tRFC = tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
}
|
||||
else if (refreshMode == 2)
|
||||
{
|
||||
tREFI = tCK * (parseUint(memspec[timings]["REFI"], "REFI") / 2);
|
||||
tRFC = tCK * parseUint(memspec[timings]["RFC2"], "RFC2");
|
||||
}
|
||||
else if (refreshMode == 4)
|
||||
{
|
||||
tREFI = tCK * (parseUint(memspec[timings]["REFI"], "REFI") / 2);
|
||||
tRFC = tCK * parseUint(memspec[timings]["RFC4"], "RFC4");
|
||||
}
|
||||
else
|
||||
SC_REPORT_FATAL("ConfigurationLoader", "Refresh Mode not supported");
|
||||
|
||||
tRP = tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
tRRD_S = tCK * parseUint(memspec[timings]["RRD_S"], "RRD_S");
|
||||
tRRD_L = tCK * parseUint(memspec[timings]["RRD_L"], "RRD_L");
|
||||
tWTR_S = tCK * parseUint(memspec[timings]["WTR_S"], "WTR_S");
|
||||
tWTR_L = tCK * parseUint(memspec[timings]["WTR_L"], "WTR_L");
|
||||
tAL = tCK * parseUint(memspec[timings]["AL"], "AL");
|
||||
tXPDLL = tCK * parseUint(memspec[timings]["XPDLL"], "XPDLL");
|
||||
tXSDLL = tCK * parseUint(memspec[timings]["XSDLL"], "XSDLL");
|
||||
tACTPDEN = tCK * parseUint(memspec[timings]["ACTPDEN"], "ACTPDEN");
|
||||
tPRPDEN = tCK * parseUint(memspec[timings]["PRPDEN"], "PRPDEN");
|
||||
tREFPDEN = tCK * parseUint(memspec[timings]["REFPDEN"], "REFPDEN");
|
||||
tRTRS = tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
std::string power = "mempowerspec";
|
||||
iDD0 = parseUdouble(memspec[power]["idd0"], "idd0");
|
||||
iDD2N = parseUdouble(memspec[power]["idd2n"], "idd2n");
|
||||
iDD3N = parseUdouble(memspec[power]["idd3n"], "idd3n");
|
||||
iDD4R = parseUdouble(memspec[power]["idd4r"], "idd4r");
|
||||
iDD4W = parseUdouble(memspec[power]["idd4w"], "idd4w");
|
||||
iDD5 = parseUdouble(memspec[power]["idd5"], "idd5");
|
||||
iDD6 = parseUdouble(memspec[power]["idd6"], "idd6");
|
||||
vDD = parseUdouble(memspec[power]["vdd"], "vdd");
|
||||
iDD02 = parseUdouble(memspec[power]["idd02"], "idd02");
|
||||
iDD2P0 = parseUdouble(memspec[power]["idd2p0"], "idd2p0");
|
||||
iDD2P1 = parseUdouble(memspec[power]["idd2p1"], "idd2p1");
|
||||
iDD3P0 = parseUdouble(memspec[power]["idd3p0"], "idd3p0");
|
||||
iDD3P1 = parseUdouble(memspec[power]["idd3p1"], "idd3p1");
|
||||
iDD62 = parseUdouble(memspec[power]["idd62"], "idd62");
|
||||
vDD2 = parseUdouble(memspec[power]["vdd2"], "vdd2");
|
||||
}
|
||||
|
||||
sc_time MemSpecDDR4::getRefreshIntervalAB() const
|
||||
{
|
||||
|
||||
@@ -37,9 +37,13 @@
|
||||
#define MEMSPECDDR4_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
struct MemSpecDDR4 final : public MemSpec
|
||||
class MemSpecDDR4 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
MemSpecDDR4(nlohmann::json &);
|
||||
|
||||
// Memspec Variables:
|
||||
sc_time tCKE; // min time between pdx and pde
|
||||
sc_time tPD; // min time in pdn
|
||||
|
||||
@@ -36,6 +36,63 @@
|
||||
#include "MemSpecGDDR5.h"
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecGDDR5::MemSpecGDDR5(json &memspec) : MemSpec(memspec)
|
||||
{
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"], "nbrOfRanks");
|
||||
banksPerRank = parseUint(memspec[arch]["nbrOfBanks"], "nbrOfBanks");
|
||||
groupsPerRank = parseUint(memspec[arch]["nbrOfBankGroups"], "nbrOfBankGroups");
|
||||
banksPerGroup = banksPerRank / groupsPerRank;
|
||||
numberOfBanks = banksPerRank * numberOfRanks;
|
||||
numberOfBankGroups = groupsPerRank * numberOfRanks;
|
||||
|
||||
// MemTimings specific for GDDR5
|
||||
std::string timings = "memtimingspec";
|
||||
tRP = tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
tRAS = tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
tRC = tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
tRCDRD = tCK * parseUint(memspec[timings]["RCDRD"], "RCDRD");
|
||||
tRCDWR = tCK * parseUint(memspec[timings]["RCDWR"], "RCDWR");
|
||||
tRTP = tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
tRRDS = tCK * parseUint(memspec[timings]["RRDS"], "RRDS");
|
||||
tRRDL = tCK * parseUint(memspec[timings]["RRDL"], "RRDL");
|
||||
tCCDS = tCK * parseUint(memspec[timings]["CCDS"], "CCDS");
|
||||
tCCDL = tCK * parseUint(memspec[timings]["CCDL"], "CCDL");
|
||||
tCL = tCK * parseUint(memspec[timings]["CL"], "CL");
|
||||
tWCK2CKPIN = tCK * parseUint(memspec[timings]["WCK2CKPIN"], "WCK2CKPIN");
|
||||
tWCK2CK = tCK * parseUint(memspec[timings]["WCK2CK"], "WCK2CK");
|
||||
tWCK2DQO = tCK * parseUint(memspec[timings]["WCK2DQO"], "WCK2DQO");
|
||||
tRTW = tCK * parseUint(memspec[timings]["RTW"], "RTW");
|
||||
tWL = tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
tWCK2DQI = tCK * parseUint(memspec[timings]["WCK2DQI"], "WCK2DQI");
|
||||
tWR = tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
tWTRS = tCK * parseUint(memspec[timings]["WTRS"], "WTRS");
|
||||
tWTRL = tCK * parseUint(memspec[timings]["WTRL"], "WTRL");
|
||||
tCKE = tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
tPD = tCK * parseUint(memspec[timings]["PD"], "PD");
|
||||
tXPN = tCK * parseUint(memspec[timings]["XPN"], "XPN");
|
||||
tREFI = tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
tREFIPB = tCK * parseUint(memspec[timings]["REFIPB"], "REFIPB");
|
||||
tRFC = tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
tRFCPB = tCK * parseUint(memspec[timings]["RFCPB"], "RFCPB");
|
||||
tRREFD = tCK * parseUint(memspec[timings]["RREFD"], "RREFD");
|
||||
tXS = tCK * parseUint(memspec[timings]["XS"], "XS");
|
||||
tFAW = tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
t32AW = tCK * parseUint(memspec[timings]["32AW"], "32AW");
|
||||
// tRDSRE = tCL + tWCK2CKPIN + tWCK2CK
|
||||
// + tWCK2DQO + burstLength / dataRate * tCK;
|
||||
// tWRSRE = tWL + tWCK2CKPIN + tWCK2CK
|
||||
// + tWCK2DQI + burstLength / dataRate * tCK;
|
||||
tPPD = tCK * parseUint(memspec[timings]["PPD"], "PPD");
|
||||
tLK = tCK * parseUint(memspec[timings]["LK"], "LK");
|
||||
tRTRS = tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
sc_time MemSpecGDDR5::getRefreshIntervalAB() const
|
||||
{
|
||||
|
||||
@@ -37,9 +37,13 @@
|
||||
#define MEMSPECGDDR5_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
struct MemSpecGDDR5 final : public MemSpec
|
||||
class MemSpecGDDR5 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
MemSpecGDDR5(nlohmann::json &);
|
||||
|
||||
// Memspec Variables:
|
||||
sc_time tRP;
|
||||
sc_time tRAS;
|
||||
|
||||
@@ -36,6 +36,63 @@
|
||||
#include "MemSpecGDDR5X.h"
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecGDDR5X::MemSpecGDDR5X(json &memspec) : MemSpec(memspec)
|
||||
{
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"], "nbrOfRanks");
|
||||
banksPerRank = parseUint(memspec[arch]["nbrOfBanks"], "nbrOfBanks");
|
||||
groupsPerRank = parseUint(memspec[arch]["nbrOfBankGroups"], "nbrOfBankGroups");
|
||||
banksPerGroup = banksPerRank / groupsPerRank;
|
||||
numberOfBanks = banksPerRank * numberOfRanks;
|
||||
numberOfBankGroups = groupsPerRank * numberOfRanks;
|
||||
|
||||
// MemTimings specific for GDDR5X
|
||||
std::string timings = "memtimingspec";
|
||||
tRP = tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
tRAS = tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
tRC = tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
tRCDRD = tCK * parseUint(memspec[timings]["RCDRD"], "RCDRD");
|
||||
tRCDWR = tCK * parseUint(memspec[timings]["RCDWR"], "RCDWR");
|
||||
tRTP = tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
tRRDS = tCK * parseUint(memspec[timings]["RRDS"], "RRDS");
|
||||
tRRDL = tCK * parseUint(memspec[timings]["RRDL"], "RRDL");
|
||||
tCCDS = tCK * parseUint(memspec[timings]["CCDS"], "CCDS");
|
||||
tCCDL = tCK * parseUint(memspec[timings]["CCDL"], "CCDL");
|
||||
tRL = tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
tWCK2CKPIN = tCK * parseUint(memspec[timings]["WCK2CKPIN"], "WCK2CKPIN");
|
||||
tWCK2CK = tCK * parseUint(memspec[timings]["WCK2CK"], "WCK2CK");
|
||||
tWCK2DQO = tCK * parseUint(memspec[timings]["WCK2DQO"], "WCK2DQO");
|
||||
tRTW = tCK * parseUint(memspec[timings]["RTW"], "RTW");
|
||||
tWL = tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
tWCK2DQI = tCK * parseUint(memspec[timings]["WCK2DQI"], "WCK2DQI");
|
||||
tWR = tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
tWTRS = tCK * parseUint(memspec[timings]["WTRS"], "WTRS");
|
||||
tWTRL = tCK * parseUint(memspec[timings]["WTRL"], "WTRL");
|
||||
tCKE = tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
tPD = tCK * parseUint(memspec[timings]["PD"], "PD");
|
||||
tXP = tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
tREFI = tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
tREFIPB = tCK * parseUint(memspec[timings]["REFIPB"], "REFIPB");
|
||||
tRFC = tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
tRFCPB = tCK * parseUint(memspec[timings]["RFCPB"], "RFCPB");
|
||||
tRREFD = tCK * parseUint(memspec[timings]["RREFD"], "RREFD");
|
||||
tXS = tCK * parseUint(memspec[timings]["XS"], "XS");
|
||||
tFAW = tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
t32AW = tCK * parseUint(memspec[timings]["32AW"], "32AW");
|
||||
// tRDSRE = tRL + tWCK2CKPIN + tWCK2CK
|
||||
// + tWCK2DQO + burstLength / dataRate * tCK;
|
||||
// tWRSRE = tWL + tWCK2CKPIN + tWCK2CK
|
||||
// + tWCK2DQI + burstLength / dataRate * tCK;
|
||||
tPPD = tCK * parseUint(memspec[timings]["PPD"], "PPD");
|
||||
tLK = tCK * parseUint(memspec[timings]["LK"], "LK");
|
||||
tRTRS = tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
sc_time MemSpecGDDR5X::getRefreshIntervalAB() const
|
||||
{
|
||||
|
||||
@@ -37,9 +37,13 @@
|
||||
#define MEMSPECGDDR5X_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
struct MemSpecGDDR5X final : public MemSpec
|
||||
class MemSpecGDDR5X final : public MemSpec
|
||||
{
|
||||
public:
|
||||
MemSpecGDDR5X(nlohmann::json &);
|
||||
|
||||
// Memspec Variables:
|
||||
sc_time tRP;
|
||||
sc_time tRAS;
|
||||
|
||||
@@ -36,6 +36,65 @@
|
||||
#include "MemSpecGDDR6.h"
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecGDDR6::MemSpecGDDR6(json &memspec) : MemSpec(memspec)
|
||||
{
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"], "nbrOfRanks");
|
||||
banksPerRank = parseUint(memspec[arch]["nbrOfBanks"], "nbrOfBanks");
|
||||
groupsPerRank = parseUint(memspec[arch]["nbrOfBankGroups"], "nbrOfBankGroups");
|
||||
banksPerGroup = banksPerRank / groupsPerRank;
|
||||
numberOfBanks = banksPerRank * numberOfRanks;
|
||||
numberOfBankGroups = groupsPerRank * numberOfRanks;
|
||||
|
||||
// MemTimings specific for GDDR6
|
||||
std::string timings = "memtimingspec";
|
||||
tRP = tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
tRAS = tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
tRC = tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
tRCDRD = tCK * parseUint(memspec[timings]["RCDRD"], "RCDRD");
|
||||
tRCDWR = tCK * parseUint(memspec[timings]["RCDWR"], "RCDWR");
|
||||
tRTP = tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
tRRDS = tCK * parseUint(memspec[timings]["RRDS"], "RRDS");
|
||||
tRRDL = tCK * parseUint(memspec[timings]["RRDL"], "RRDL");
|
||||
tCCDS = tCK * parseUint(memspec[timings]["CCDS"], "CCDS");
|
||||
tCCDL = tCK * parseUint(memspec[timings]["CCDL"], "CCDL");
|
||||
tRL = tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
tWCK2CKPIN = tCK * parseUint(memspec[timings]["WCK2CKPIN"], "WCK2CKPIN");
|
||||
tWCK2CK = tCK * parseUint(memspec[timings]["WCK2CK"], "WCK2CK");
|
||||
tWCK2DQO = tCK * parseUint(memspec[timings]["WCK2DQO"], "WCK2DQO");
|
||||
tRTW = tCK * parseUint(memspec[timings]["RTW"], "RTW");
|
||||
tWL = tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
tWCK2DQI = tCK * parseUint(memspec[timings]["WCK2DQI"], "WCK2DQI");
|
||||
tWR = tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
tWTRS = tCK * parseUint(memspec[timings]["WTRS"], "WTRS");
|
||||
tWTRL = tCK * parseUint(memspec[timings]["WTRL"], "WTRL");
|
||||
tPD = tCK * parseUint(memspec[timings]["PD"], "PD");
|
||||
tCKESR = tCK * parseUint(memspec[timings]["CKESR"], "CKESR");
|
||||
tXP = tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
tREFI = tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
tREFIPB = tCK * parseUint(memspec[timings]["REFIPB"], "REFIPB");
|
||||
tRFC = tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
tRFCPB = tCK * parseUint(memspec[timings]["RFCPB"], "RFCPB");
|
||||
tRREFD = tCK * parseUint(memspec[timings]["RREFD"], "RREFD");
|
||||
tXS = tCK * parseUint(memspec[timings]["XS"], "XS");
|
||||
tFAW = tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
// tRDSRE = tRL + tWCK2CKPIN + tWCK2CK
|
||||
// + tWCK2DQO + burstLength / dataRate * tCK;
|
||||
// tWRSRE = tWL + tWCK2CKPIN + tWCK2CK
|
||||
// + tWCK2DQI + burstLength / dataRate * tCK;
|
||||
tPPD = tCK * parseUint(memspec[timings]["PPD"], "PPD");
|
||||
tLK = tCK * parseUint(memspec[timings]["LK"], "LK");
|
||||
tACTPDE = tCK * parseUint(memspec[timings]["ACTPDE"], "ACTPDE");
|
||||
tPREPDE = tCK * parseUint(memspec[timings]["PREPDE"], "PREPDE");
|
||||
tREFPDE = tCK * parseUint(memspec[timings]["REFPDE"], "REFPDE");
|
||||
tRTRS = tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
sc_time MemSpecGDDR6::getRefreshIntervalAB() const
|
||||
{
|
||||
|
||||
@@ -37,9 +37,12 @@
|
||||
#define MEMSPECGDDR6_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
struct MemSpecGDDR6 final : public MemSpec
|
||||
{
|
||||
MemSpecGDDR6(nlohmann::json &);
|
||||
|
||||
// Memspec Variables:
|
||||
sc_time tRP;
|
||||
sc_time tRAS;
|
||||
|
||||
@@ -36,10 +36,55 @@
|
||||
#include "MemSpecHBM2.h"
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecHBM2::MemSpecHBM2()
|
||||
MemSpecHBM2::MemSpecHBM2(json &memspec) : MemSpec(memspec)
|
||||
{
|
||||
commandLengthInCycles[Command::ACT] = 2;
|
||||
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"], "nbrOfRanks");
|
||||
banksPerRank = parseUint(memspec[arch]["nbrOfBanks"], "nbrOfBanks");
|
||||
groupsPerRank = parseUint(memspec[arch]["nbrOfBankGroups"], "nbrOfBankGroups");
|
||||
banksPerGroup = banksPerRank / groupsPerRank;
|
||||
numberOfBanks = banksPerRank * numberOfRanks;
|
||||
numberOfBankGroups = groupsPerRank * numberOfRanks;
|
||||
|
||||
// MemTimings specific for HBM2
|
||||
std::string timings = "memtimingspec";
|
||||
tDQSCK = tCK * parseUint(memspec[timings]["DQSCK"], "DQSCK");
|
||||
tRC = tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
tRAS = tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
tRCDRD = tCK * parseUint(memspec[timings]["RCDRD"], "RCDRD");
|
||||
tRCDWR = tCK * parseUint(memspec[timings]["RCDWR"], "RCDWR");
|
||||
tRRDL = tCK * parseUint(memspec[timings]["RRDL"], "RRDL");
|
||||
tRRDS = tCK * parseUint(memspec[timings]["RRDS"], "RRDS");
|
||||
tFAW = tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
tRTP = tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
tRP = tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
tRL = tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
tWL = tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
tPL = tCK * parseUint(memspec[timings]["PL"], "PL");
|
||||
tWR = tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
tCCDL = tCK * parseUint(memspec[timings]["CCDL"], "CCDL");
|
||||
tCCDS = tCK * parseUint(memspec[timings]["CCDS"], "CCDS");
|
||||
tWTRL = tCK * parseUint(memspec[timings]["WTRL"], "WTRL");
|
||||
tWTRS = tCK * parseUint(memspec[timings]["WTRS"], "WTRS");
|
||||
tRTW = tCK * parseUint(memspec[timings]["RTW"], "RTW");
|
||||
tXP = tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
tCKE = tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
tPD = tCKE;
|
||||
tCKESR = tCKE + tCK;
|
||||
tXS = tCK * parseUint(memspec[timings]["XS"], "XS");
|
||||
tRFC = tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
tRFCSB = tCK * parseUint(memspec[timings]["RFCSB"], "RFCSB");
|
||||
tRREFD = tCK * parseUint(memspec[timings]["RREFD"], "RREFD");
|
||||
tREFI = tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
tREFISB = tCK * parseUint(memspec[timings]["REFISB"], "REFISB");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
sc_time MemSpecHBM2::getRefreshIntervalAB() const
|
||||
|
||||
@@ -37,10 +37,12 @@
|
||||
#define MEMSPECHBM2_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
struct MemSpecHBM2 final : public MemSpec
|
||||
class MemSpecHBM2 final : public MemSpec
|
||||
{
|
||||
MemSpecHBM2();
|
||||
public:
|
||||
MemSpecHBM2(nlohmann::json &);
|
||||
|
||||
// Memspec Variables:
|
||||
sc_time tDQSCK;
|
||||
|
||||
@@ -36,8 +36,9 @@
|
||||
#include "MemSpecLPDDR4.h"
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecLPDDR4::MemSpecLPDDR4()
|
||||
MemSpecLPDDR4::MemSpecLPDDR4(json &memspec) : MemSpec(memspec)
|
||||
{
|
||||
commandLengthInCycles[Command::ACT] = 4;
|
||||
commandLengthInCycles[Command::PRE] = 2;
|
||||
@@ -50,6 +51,52 @@ MemSpecLPDDR4::MemSpecLPDDR4()
|
||||
commandLengthInCycles[Command::REFB] = 2;
|
||||
commandLengthInCycles[Command::SREFEN] = 2;
|
||||
commandLengthInCycles[Command::SREFEX] = 2;
|
||||
|
||||
// MemArchitecture:
|
||||
std::string arch = "memarchitecturespec";
|
||||
numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"],"nbrOfRanks");
|
||||
banksPerRank = parseUint(memspec[arch]["nbrOfBanks"],"nbrOfBanks");
|
||||
groupsPerRank = 1;
|
||||
banksPerGroup = banksPerRank / groupsPerRank;
|
||||
numberOfBanks = banksPerRank * numberOfRanks;
|
||||
numberOfBankGroups = groupsPerRank * numberOfRanks;
|
||||
|
||||
// MemTimings specific for LPDDR4
|
||||
std::string timings = "memtimingspec";
|
||||
tREFI = tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
tREFIpb = tCK * parseUint(memspec[timings]["REFIPB"], "REFIPB");
|
||||
tRFCab = tCK * parseUint(memspec[timings]["RFCAB"], "RFCAB");
|
||||
tRFCpb = tCK * parseUint(memspec[timings]["RFCPB"], "RFCPB");
|
||||
tRPab = tCK * parseUint(memspec[timings]["RPAB"], "RPAB");
|
||||
tRPpb = tCK * parseUint(memspec[timings]["RPPB"], "RPPB");
|
||||
tRCab = tCK * parseUint(memspec[timings]["RCAB"], "RCAB");
|
||||
tRCpb = tCK * parseUint(memspec[timings]["RCPB"], "RCPB");
|
||||
tPPD = tCK * parseUint(memspec[timings]["PPD"], "PPD");
|
||||
tRAS = tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
tRCD = tCK * parseUint(memspec[timings]["RCD"], "RCD");
|
||||
tFAW = tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
tRRD = tCK * parseUint(memspec[timings]["RRD"], "RRD");
|
||||
tCCD = tCK * parseUint(memspec[timings]["CCD"], "CCD");
|
||||
tRL = tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
tRPST = tCK * parseUint(memspec[timings]["RPST"], "RPST");
|
||||
tDQSCK = tCK * parseUint(memspec[timings]["DQSCK"], "DQSCK");
|
||||
tRTP = tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
tWL = tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
tDQSS = tCK * parseUint(memspec[timings]["DQSS"], "DQSS");
|
||||
tDQS2DQ = tCK * parseUint(memspec[timings]["DQS2DQ"], "DQS2DQ");
|
||||
tWR = tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
tWPRE = tCK * parseUint(memspec[timings]["WPRE"], "WPRE");
|
||||
tWTR = tCK * parseUint(memspec[timings]["WTR"], "WTR");
|
||||
tXP = tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
tSR = tCK * parseUint(memspec[timings]["SR"], "SR");
|
||||
tXSR = tCK * parseUint(memspec[timings]["XSR"], "XSR");
|
||||
tESCKE = tCK * parseUint(memspec[timings]["ESCKE"], "ESCKE");
|
||||
tCKE = tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
tCMDCKE = tCK * parseUint(memspec[timings]["CMDCKE"], "CMDCKE");
|
||||
tRTRS = tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
sc_time MemSpecLPDDR4::getRefreshIntervalAB() const
|
||||
|
||||
@@ -37,10 +37,12 @@
|
||||
#define MEMSPECLPDDR4_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
struct MemSpecLPDDR4 final : public MemSpec
|
||||
class MemSpecLPDDR4 final : public MemSpec
|
||||
{
|
||||
MemSpecLPDDR4();
|
||||
public:
|
||||
MemSpecLPDDR4(nlohmann::json &);
|
||||
|
||||
// Memspec Variables:
|
||||
sc_time tREFI;
|
||||
|
||||
@@ -36,6 +36,70 @@
|
||||
#include "MemSpecWideIO.h"
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecWideIO::MemSpecWideIO(json &memspec) : MemSpec(memspec)
|
||||
{
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"], "nbrOfRanks");
|
||||
banksPerRank = parseUint(memspec[arch]["nbrOfBanks"], "nbrOfBanks");
|
||||
groupsPerRank = 1;
|
||||
banksPerGroup = banksPerRank / groupsPerRank;
|
||||
numberOfBanks = banksPerRank * numberOfRanks;
|
||||
numberOfBankGroups = groupsPerRank * numberOfRanks;
|
||||
|
||||
// MemTimings specific for WideIO
|
||||
std::string timings = "memtimingspec";
|
||||
tCKE = tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
tCKESR = tCK * parseUint(memspec[timings]["CKESR"], "CKESR");
|
||||
tDQSCK = tCK * parseUint(memspec[timings]["DQSCK"], "DQSCK");
|
||||
tAC = tCK * parseUint(memspec[timings]["AC"], "AC");
|
||||
tRAS = tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
tRC = tCK * parseUint(memspec[timings]["RC"], "RC");
|
||||
tRCD = tCK * parseUint(memspec[timings]["RCD"], "RCD");
|
||||
tRL = tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
tWL = tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
tWR = tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
tXP = tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
tXSR = tCK * parseUint(memspec[timings]["XSR"], "XSR");
|
||||
tCCD_R = tCK * parseUint(memspec[timings]["CCD_R"], "CCD_R");
|
||||
tCCD_W = tCK * parseUint(memspec[timings]["CCD_W"], "CCD_W");
|
||||
tREFI = tCK * parseUint(memspec[timings]["REFI"], "REFI");
|
||||
tRFC = tCK * parseUint(memspec[timings]["RFC"], "RFC");
|
||||
tRP = tCK * parseUint(memspec[timings]["RP"], "RP");
|
||||
tRRD = tCK * parseUint(memspec[timings]["RRD"], "RRD");
|
||||
tTAW = tCK * parseUint(memspec[timings]["TAW"], "TAW");
|
||||
tWTR = tCK * parseUint(memspec[timings]["WTR"], "WTR");
|
||||
tRTRS = tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
std::string power = "mempowerspec";
|
||||
iDD0 = parseUdouble(memspec[power]["idd0"], "idd0");
|
||||
iDD2N = parseUdouble(memspec[power]["idd2n"], "idd2n");
|
||||
iDD3N = parseUdouble(memspec[power]["idd3n"], "idd3n");
|
||||
iDD4R = parseUdouble(memspec[power]["idd4r"], "idd4r");
|
||||
iDD4W = parseUdouble(memspec[power]["idd4w"], "idd4w");
|
||||
iDD5 = parseUdouble(memspec[power]["idd5"], "idd5");
|
||||
iDD6 = parseUdouble(memspec[power]["idd6"], "idd6");
|
||||
vDD = parseUdouble(memspec[power]["vdd"], "vdd");
|
||||
iDD02 = parseUdouble(memspec[power]["idd02"], "idd02");
|
||||
iDD2P0 = parseUdouble(memspec[power]["idd2p0"], "idd2p0");
|
||||
iDD2P02 = parseUdouble(memspec[power]["idd2p02"], "idd2p02");
|
||||
iDD2P1 = parseUdouble(memspec[power]["idd2p1"], "idd2p1");
|
||||
iDD2P12 = parseUdouble(memspec[power]["idd2p12"], "idd2p12");
|
||||
iDD2N2 = parseUdouble(memspec[power]["idd2n2"], "idd2n2");
|
||||
iDD3P0 = parseUdouble(memspec[power]["idd3p0"], "idd3p0");
|
||||
iDD3P02 = parseUdouble(memspec[power]["idd3p02"], "idd3p02");
|
||||
iDD3P1 = parseUdouble(memspec[power]["idd3p1"], "idd3p1");
|
||||
iDD3P12 = parseUdouble(memspec[power]["idd3p12"], "idd3p12");
|
||||
iDD3N2 = parseUdouble(memspec[power]["idd3n2"], "idd3n2");
|
||||
iDD4R2 = parseUdouble(memspec[power]["idd4r2"], "idd4r2");
|
||||
iDD4W2 = parseUdouble(memspec[power]["idd4w2"], "idd4w2");
|
||||
iDD52 = parseUdouble(memspec[power]["idd52"], "idd52");
|
||||
iDD62 = parseUdouble(memspec[power]["idd62"], "idd62");
|
||||
vDD2 = parseUdouble(memspec[power]["vdd2"], "vdd2");
|
||||
}
|
||||
|
||||
sc_time MemSpecWideIO::getRefreshIntervalAB() const
|
||||
{
|
||||
|
||||
@@ -37,9 +37,13 @@
|
||||
#define MEMSPECWIDEIO_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
struct MemSpecWideIO final : public MemSpec
|
||||
class MemSpecWideIO final : public MemSpec
|
||||
{
|
||||
public:
|
||||
MemSpecWideIO(nlohmann::json &);
|
||||
|
||||
// Memspec Variables:
|
||||
sc_time tCKE; // min time in pdna or pdnp
|
||||
sc_time tCKESR; // min time in sref
|
||||
|
||||
@@ -36,6 +36,52 @@
|
||||
#include "MemSpecWideIO2.h"
|
||||
|
||||
using namespace tlm;
|
||||
using json = nlohmann::json;
|
||||
|
||||
MemSpecWideIO2::MemSpecWideIO2(json &memspec) : MemSpec(memspec)
|
||||
{
|
||||
// MemArchitecture
|
||||
std::string arch = "memarchitecturespec";
|
||||
numberOfRanks = parseUint(memspec[arch]["nbrOfRanks"], "nbrOfRanks");
|
||||
banksPerRank = parseUint(memspec[arch]["nbrOfBanks"], "nbrOfBanks");
|
||||
groupsPerRank = 1;
|
||||
banksPerGroup = banksPerRank / groupsPerRank;
|
||||
numberOfBanks = banksPerRank * numberOfRanks;
|
||||
numberOfBankGroups = groupsPerRank * numberOfRanks;
|
||||
|
||||
// MemTimings specific for WideIO2
|
||||
std::string timings = "memtimingspec";
|
||||
tDQSCK = tCK * parseUint(memspec[timings]["DQSCK"], "DQSCK");
|
||||
tDQSS = tCK * parseUint(memspec[timings]["DQSS"], "DQSS");
|
||||
tCKE = tCK * parseUint(memspec[timings]["CKE"], "CKE");
|
||||
tRL = tCK * parseUint(memspec[timings]["RL"], "RL");
|
||||
tWL = tCK * parseUint(memspec[timings]["WL"], "WL");
|
||||
tRCpb = tCK * parseUint(memspec[timings]["RCPB"], "RCPB");
|
||||
tRCab = tCK * parseUint(memspec[timings]["RCAB"], "RCAB");
|
||||
tCKESR = tCK * parseUint(memspec[timings]["CKESR"], "CKESR");
|
||||
tXSR = tCK * parseUint(memspec[timings]["XSR"], "XSR");
|
||||
tXP = tCK * parseUint(memspec[timings]["XP"], "XP");
|
||||
tCCD = tCK * parseUint(memspec[timings]["CCD"], "CCD");
|
||||
tRTP = tCK * parseUint(memspec[timings]["RTP"], "RTP");
|
||||
tRCD = tCK * parseUint(memspec[timings]["RCD"], "RCD");
|
||||
tRPpb = tCK * parseUint(memspec[timings]["RPPB"], "RPPB");
|
||||
tRPab = tCK * parseUint(memspec[timings]["RPAB"], "RPAB");
|
||||
tRAS = tCK * parseUint(memspec[timings]["RAS"], "RAS");
|
||||
tWR = tCK * parseUint(memspec[timings]["WR"], "WR");
|
||||
tWTR = tCK * parseUint(memspec[timings]["WTR"], "WTR");
|
||||
tRRD = tCK * parseUint(memspec[timings]["RRD"], "RRD");
|
||||
tFAW = tCK * parseUint(memspec[timings]["FAW"], "FAW");
|
||||
tREFI = tCK * (unsigned)(parseUint(memspec[timings]["REFI"], "REFI")
|
||||
* parseUdouble(memspec[timings]["REFM"], "REFM"));
|
||||
tREFIpb = tCK * (unsigned)(parseUint(memspec[timings]["REFIPB"], "REFIPB")
|
||||
* parseUdouble(memspec[timings]["REFM"], "REFM"));
|
||||
tRFCab = tCK * parseUint(memspec[timings]["RFCAB"], "RFCAB");
|
||||
tRFCpb = tCK * parseUint(memspec[timings]["RFCPB"], "RFCPB");
|
||||
tRTRS = tCK * parseUint(memspec[timings]["RTRS"], "RTRS");
|
||||
|
||||
// Currents and voltages
|
||||
// TODO: to be completed
|
||||
}
|
||||
|
||||
sc_time MemSpecWideIO2::getRefreshIntervalAB() const
|
||||
{
|
||||
|
||||
@@ -37,9 +37,13 @@
|
||||
#define MEMSPECWIDEIO2_H
|
||||
|
||||
#include "MemSpec.h"
|
||||
#include "../../common/third_party/nlohmann/single_include/nlohmann/json.hpp"
|
||||
|
||||
struct MemSpecWideIO2 final : public MemSpec
|
||||
class MemSpecWideIO2 final : public MemSpec
|
||||
{
|
||||
public:
|
||||
MemSpecWideIO2(nlohmann::json &);
|
||||
|
||||
// Memspec Variables:
|
||||
sc_time tDQSCK;
|
||||
sc_time tDQSS;
|
||||
|
||||
@@ -89,16 +89,16 @@ DRAMSys::DRAMSys(sc_module_name name,
|
||||
Configuration::getInstance().setPathToResources(pathToResources);
|
||||
|
||||
// Load config and initialize modules
|
||||
ConfigurationLoader::loadMemSpec(Configuration::getInstance(),
|
||||
pathToResources
|
||||
+ "configs/memspecs/"
|
||||
+ memspec);
|
||||
|
||||
ConfigurationLoader::loadMCConfig(Configuration::getInstance(),
|
||||
pathToResources
|
||||
+ "configs/mcconfigs/"
|
||||
+ mcconfig);
|
||||
|
||||
ConfigurationLoader::loadMemSpec(Configuration::getInstance(),
|
||||
pathToResources
|
||||
+ "configs/memspecs/"
|
||||
+ memspec);
|
||||
|
||||
ConfigurationLoader::loadSimConfig(Configuration::getInstance(),
|
||||
pathToResources
|
||||
+ "configs/simulator/"
|
||||
|
||||
Reference in New Issue
Block a user