|
|
|
|
@@ -103,15 +103,12 @@ void ConfigurationLoader::loadConfig(Configuration &config,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadConfigJson(Configuration &config,
|
|
|
|
|
json::object_t *configNode)
|
|
|
|
|
json::object_t *configNode)
|
|
|
|
|
{
|
|
|
|
|
json j = *configNode;
|
|
|
|
|
|
|
|
|
|
for (auto& x : j.items())
|
|
|
|
|
{
|
|
|
|
|
config.setParameter(x.key(), x.value());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (auto& x : j.items()) {
|
|
|
|
|
config.setParameter(x.key(), x.value());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadConfigFromUri(Configuration &config,
|
|
|
|
|
@@ -135,17 +132,18 @@ void ConfigurationLoader::loadMCConfig(Configuration &config,
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadMemSpec(Configuration &config, std::string memspecUri)
|
|
|
|
|
{
|
|
|
|
|
tinyxml2::XMLDocument doc;
|
|
|
|
|
config.memspecUri = memspecUri;
|
|
|
|
|
loadXML(memspecUri, doc);
|
|
|
|
|
XMLElement *memspec = doc.FirstChildElement("memspec");
|
|
|
|
|
json doc = json::parse(std::ifstream(memspecUri));
|
|
|
|
|
auto memspec = doc["memspec"].get_ptr<json::object_t*>();
|
|
|
|
|
loadMemSpec(config, memspec);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadMemSpec(Configuration &config,
|
|
|
|
|
XMLElement *memspec)
|
|
|
|
|
json::object_t *memspec)
|
|
|
|
|
{
|
|
|
|
|
std::string memoryType = queryStringParameter(memspec, "memoryType");
|
|
|
|
|
using json = nlohmann::json;
|
|
|
|
|
json j = *memspec;
|
|
|
|
|
auto memoryType = j["memoryType"];
|
|
|
|
|
if (memoryType == "DDR4")
|
|
|
|
|
{
|
|
|
|
|
Configuration::getInstance().memSpec = new MemSpecDDR4();
|
|
|
|
|
@@ -204,365 +202,368 @@ void ConfigurationLoader::loadMemSpec(Configuration &config,
|
|
|
|
|
reportFatal("ConfigurationLoader", "Unsupported DRAM type");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadCommons(Configuration &config, XMLElement *xmlSpec)
|
|
|
|
|
void ConfigurationLoader::loadCommons(Configuration &config, json::object_t *jsonSpec)
|
|
|
|
|
{
|
|
|
|
|
MemSpec *memSpec = config.memSpec;
|
|
|
|
|
json j = *jsonSpec;
|
|
|
|
|
memSpec->memoryId = stringParameter(j["memoryId"]);
|
|
|
|
|
memSpec->memoryType = stringParameter(j["memoryType"]);
|
|
|
|
|
|
|
|
|
|
memSpec->memoryId = queryStringParameter(xmlSpec, "memoryId");
|
|
|
|
|
memSpec->memoryType = queryStringParameter(xmlSpec, "memoryType");
|
|
|
|
|
|
|
|
|
|
// MemArchitecture
|
|
|
|
|
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
|
|
|
|
memSpec->burstLength = queryUIntParameter(architecture, "burstLength");
|
|
|
|
|
memSpec->dataRate = queryUIntParameter(architecture, "dataRate");
|
|
|
|
|
memSpec->numberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
|
|
|
|
memSpec->numberOfColumns = queryUIntParameter(architecture, "nbrOfColumns");
|
|
|
|
|
memSpec->bitWidth = queryUIntParameter(architecture, "width");
|
|
|
|
|
memSpec->burstLength = uIntParameter( j["memarchitecturespec"]["burstLength"],"burstLength");
|
|
|
|
|
memSpec->dataRate = uIntParameter( j["memarchitecturespec"]["dataRate"],"dataRate");
|
|
|
|
|
memSpec->numberOfRows = uIntParameter( j["memarchitecturespec"]["nbrOfRows"],"nbrOfRows");
|
|
|
|
|
memSpec->numberOfColumns = uIntParameter( j["memarchitecturespec"]["nbrOfColumns"],"nbrOfColumns");
|
|
|
|
|
memSpec->bitWidth = uIntParameter( j["memarchitecturespec"]["width"],"width");
|
|
|
|
|
|
|
|
|
|
// Clock
|
|
|
|
|
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
|
|
|
|
memSpec->fCKMHz = queryDoubleParameter(timings, "clkMhz");
|
|
|
|
|
memSpec->fCKMHz = doubleParameter(j["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, XMLElement *xmlSpec)
|
|
|
|
|
void ConfigurationLoader::loadDDR3(Configuration &config, json::object_t *jsonSpec)
|
|
|
|
|
{
|
|
|
|
|
MemSpecDDR3 *memSpec = dynamic_cast<MemSpecDDR3 *>(config.memSpec);
|
|
|
|
|
if (memSpec == nullptr)
|
|
|
|
|
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
|
|
|
|
|
|
|
|
|
// MemArchitecture
|
|
|
|
|
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
|
|
|
|
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
|
|
|
|
memSpec->groupsPerRank = 1;
|
|
|
|
|
memSpec->banksPerGroup = memSpec->banksPerRank / memSpec->groupsPerRank;
|
|
|
|
|
memSpec->numberOfBanks = memSpec->banksPerRank * memSpec->numberOfRanks;
|
|
|
|
|
json j = *jsonSpec;
|
|
|
|
|
std::string arch = "memarchitecturespec";
|
|
|
|
|
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"],"nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = uIntParameter(j[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
|
|
|
|
|
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
|
|
|
|
memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR");
|
|
|
|
|
//memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
|
|
|
|
memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
|
|
|
|
memSpec->tCCD = memSpec->tCK * queryUIntParameter(timings, "CCD");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
|
|
|
|
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
|
|
|
|
memSpec->tRRD = memSpec->tCK * queryUIntParameter(timings, "RRD");
|
|
|
|
|
memSpec->tWTR = memSpec->tCK * queryUIntParameter(timings, "WTR");
|
|
|
|
|
memSpec->tAL = memSpec->tCK * queryUIntParameter(timings, "AL");
|
|
|
|
|
memSpec->tXPDLL = memSpec->tCK * queryUIntParameter(timings, "XPDLL");
|
|
|
|
|
memSpec->tXSDLL = memSpec->tCK * queryUIntParameter(timings, "XSDLL");
|
|
|
|
|
std::string timings = "memtimingspec";
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
|
|
|
|
|
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
|
|
|
|
|
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
|
|
|
|
|
memSpec->tCCD = memSpec->tCK * uIntParameter(j[timings]["CCD"], "CCD");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
|
|
|
|
|
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
|
|
|
|
|
memSpec->tRRD = memSpec->tCK * uIntParameter(j[timings]["RRD"], "RRD");
|
|
|
|
|
memSpec->tWTR = memSpec->tCK * uIntParameter(j[timings]["WTR"], "WTR");
|
|
|
|
|
memSpec->tAL = memSpec->tCK * uIntParameter(j[timings]["AL"], "AL");
|
|
|
|
|
memSpec->tXPDLL = memSpec->tCK * uIntParameter(j[timings]["XPDLL"], "XPDLL");
|
|
|
|
|
memSpec->tXSDLL = memSpec->tCK * uIntParameter(j[timings]["XSDLL"], "XSDLL");
|
|
|
|
|
|
|
|
|
|
// Currents and voltages
|
|
|
|
|
XMLElement *powers = xmlSpec->FirstChildElement("mempowerspec");
|
|
|
|
|
memSpec->iDD0 = queryDoubleParameter(powers, "idd0");
|
|
|
|
|
memSpec->iDD2N = queryDoubleParameter(powers, "idd2n");
|
|
|
|
|
memSpec->iDD3N = queryDoubleParameter(powers, "idd3n");
|
|
|
|
|
memSpec->iDD4R = queryDoubleParameter(powers, "idd4r");
|
|
|
|
|
memSpec->iDD4W = queryDoubleParameter(powers, "idd4w");
|
|
|
|
|
memSpec->iDD5 = queryDoubleParameter(powers, "idd5");
|
|
|
|
|
memSpec->iDD6 = queryDoubleParameter(powers, "idd6");
|
|
|
|
|
memSpec->vDD = queryDoubleParameter(powers, "vdd");
|
|
|
|
|
memSpec->iDD2P0 = queryDoubleParameter(powers, "idd2p0");
|
|
|
|
|
memSpec->iDD2P1 = queryDoubleParameter(powers, "idd2p1");
|
|
|
|
|
memSpec->iDD3P0 = queryDoubleParameter(powers, "idd3p0");
|
|
|
|
|
memSpec->iDD3P1 = queryDoubleParameter(powers, "idd3p1");
|
|
|
|
|
std::string power = "mempowerspec";
|
|
|
|
|
memSpec->iDD0 = doubleParameter(j[power]["idd0"], "idd0");
|
|
|
|
|
memSpec->iDD2N = doubleParameter(j[power]["idd2n"], "idd2n");
|
|
|
|
|
memSpec->iDD3N = doubleParameter(j[power]["idd3n"], "idd3n");
|
|
|
|
|
memSpec->iDD4R = doubleParameter(j[power]["idd4r"], "idd4r");
|
|
|
|
|
memSpec->iDD4W = doubleParameter(j[power]["idd4w"], "idd4w");
|
|
|
|
|
memSpec->iDD5 = doubleParameter(j[power]["idd5"], "idd5");
|
|
|
|
|
memSpec->iDD6 = doubleParameter(j[power]["idd6"], "idd6");
|
|
|
|
|
memSpec->vDD = doubleParameter(j[power]["vdd"], "vdd");
|
|
|
|
|
memSpec->iDD2P0 = doubleParameter(j[power]["idd2p0"], "idd2p0");
|
|
|
|
|
memSpec->iDD2P1 = doubleParameter(j[power]["idd2p1"], "idd2p1");
|
|
|
|
|
memSpec->iDD3P0 = doubleParameter(j[power]["idd3p0"], "idd3p0");
|
|
|
|
|
memSpec->iDD3P1 = doubleParameter(j[power]["idd3p1"], "idd3p1");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadDDR4(Configuration &config, XMLElement *xmlSpec)
|
|
|
|
|
void ConfigurationLoader::loadDDR4(Configuration &config, json::object_t *jsonSpec)
|
|
|
|
|
{
|
|
|
|
|
MemSpecDDR4 *memSpec = dynamic_cast<MemSpecDDR4 *>(config.memSpec);
|
|
|
|
|
if (memSpec == nullptr)
|
|
|
|
|
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
|
|
|
|
json j = *jsonSpec;
|
|
|
|
|
|
|
|
|
|
// MemArchitecture
|
|
|
|
|
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
|
|
|
|
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
|
|
|
|
memSpec->groupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
|
|
|
|
std::string arch = "memarchitecturespec";
|
|
|
|
|
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"],"nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = uIntParameter(j[arch]["nbrOfBanks"],"nbrOfBanks");
|
|
|
|
|
memSpec->groupsPerRank = uIntParameter(j[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
|
|
|
|
|
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
|
|
|
|
memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR");
|
|
|
|
|
//memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
|
|
|
|
memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
|
|
|
|
memSpec->tCCD_S = memSpec->tCK * queryUIntParameter(timings, "CCD_S");
|
|
|
|
|
memSpec->tCCD_L = memSpec->tCK * queryUIntParameter(timings, "CCD_L");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
|
|
|
|
std::string timings = "memtimingspec";
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
|
|
|
|
|
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
|
|
|
|
|
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");;
|
|
|
|
|
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
|
|
|
|
|
memSpec->tCCD_S = memSpec->tCK * uIntParameter(j[timings]["CCD_S"], "CCD_S");
|
|
|
|
|
memSpec->tCCD_L = memSpec->tCK * uIntParameter(j[timings]["CCD_L"], "CCD_L");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
|
|
|
|
|
unsigned refreshMode = Configuration::getInstance().refreshMode;
|
|
|
|
|
if (refreshMode == 1)
|
|
|
|
|
{
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
|
|
|
|
|
}
|
|
|
|
|
else if (refreshMode == 2)
|
|
|
|
|
{
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * (queryUIntParameter(timings, "REFI") / 2);
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC2");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * (uIntParameter(j[timings]["REFI"], "REFI")/ 2);
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC2"], "RFC2");
|
|
|
|
|
}
|
|
|
|
|
else if (refreshMode == 4)
|
|
|
|
|
{
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * (queryUIntParameter(timings, "REFI") / 2);
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC4");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * (uIntParameter(j[timings]["REFI"], "REFI")/ 2);
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC4"], "RFC4");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
SC_REPORT_FATAL("ConfigurationLoader", "Refresh Mode not supported");
|
|
|
|
|
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
|
|
|
|
memSpec->tRRD_S = memSpec->tCK * queryUIntParameter(timings, "RRD_S");
|
|
|
|
|
memSpec->tRRD_L = memSpec->tCK * queryUIntParameter(timings, "RRD_L");
|
|
|
|
|
memSpec->tWTR_S = memSpec->tCK * queryUIntParameter(timings, "WTR_S");
|
|
|
|
|
memSpec->tWTR_L = memSpec->tCK * queryUIntParameter(timings, "WTR_L");
|
|
|
|
|
memSpec->tAL = memSpec->tCK * queryUIntParameter(timings, "AL");
|
|
|
|
|
memSpec->tXPDLL = memSpec->tCK * queryUIntParameter(timings, "XPDLL");
|
|
|
|
|
memSpec->tXSDLL = memSpec->tCK * queryUIntParameter(timings, "XSDLL");
|
|
|
|
|
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
|
|
|
|
|
memSpec->tRRD_S = memSpec->tCK * uIntParameter(j[timings]["RRD_S"], "RRD_S");
|
|
|
|
|
memSpec->tRRD_L = memSpec->tCK * uIntParameter(j[timings]["RRD_L"], "RRD_L");
|
|
|
|
|
memSpec->tWTR_S = memSpec->tCK * uIntParameter(j[timings]["WTR_S"], "WTR_S");
|
|
|
|
|
memSpec->tWTR_L = memSpec->tCK * uIntParameter(j[timings]["WTR_L"], "WTR_L");
|
|
|
|
|
memSpec->tAL = memSpec->tCK * uIntParameter(j[timings]["AL"], "AL");
|
|
|
|
|
memSpec->tXPDLL = memSpec->tCK * uIntParameter(j[timings]["XPDLL"], "XPDLL");
|
|
|
|
|
memSpec->tXSDLL = memSpec->tCK * uIntParameter(j[timings]["XSDLL"], "XSDLL");
|
|
|
|
|
|
|
|
|
|
// Currents and voltages
|
|
|
|
|
XMLElement *powers = xmlSpec->FirstChildElement("mempowerspec");
|
|
|
|
|
memSpec->iDD0 = queryDoubleParameter(powers, "idd0");
|
|
|
|
|
memSpec->iDD2N = queryDoubleParameter(powers, "idd2n");
|
|
|
|
|
memSpec->iDD3N = queryDoubleParameter(powers, "idd3n");
|
|
|
|
|
memSpec->iDD4R = queryDoubleParameter(powers, "idd4r");
|
|
|
|
|
memSpec->iDD4W = queryDoubleParameter(powers, "idd4w");
|
|
|
|
|
memSpec->iDD5 = queryDoubleParameter(powers, "idd5");
|
|
|
|
|
memSpec->iDD6 = queryDoubleParameter(powers, "idd6");
|
|
|
|
|
memSpec->vDD = queryDoubleParameter(powers, "vdd");
|
|
|
|
|
memSpec->iDD02 = queryDoubleParameter(powers, "idd02");
|
|
|
|
|
memSpec->iDD2P0 = queryDoubleParameter(powers, "idd2p0");
|
|
|
|
|
memSpec->iDD2P1 = queryDoubleParameter(powers, "idd2p1");
|
|
|
|
|
memSpec->iDD3P0 = queryDoubleParameter(powers, "idd3p0");
|
|
|
|
|
memSpec->iDD3P1 = queryDoubleParameter(powers, "idd3p1");
|
|
|
|
|
memSpec->iDD62 = queryDoubleParameter(powers, "idd62");
|
|
|
|
|
memSpec->vDD2 = queryDoubleParameter(powers, "vdd2");
|
|
|
|
|
std::string power = "mempowerspec";
|
|
|
|
|
memSpec->iDD0 = doubleParameter(j[power]["idd0"], "idd0");
|
|
|
|
|
memSpec->iDD2N = doubleParameter(j[power]["idd2n"], "idd2n");
|
|
|
|
|
memSpec->iDD3N = doubleParameter(j[power]["idd3n"], "idd3n");
|
|
|
|
|
memSpec->iDD4R = doubleParameter(j[power]["idd4r"], "idd4r");
|
|
|
|
|
memSpec->iDD4W = doubleParameter(j[power]["idd4w"], "idd4w");
|
|
|
|
|
memSpec->iDD5 = doubleParameter(j[power]["idd5"], "idd5");
|
|
|
|
|
memSpec->iDD6 = doubleParameter(j[power]["idd6"], "idd6");
|
|
|
|
|
memSpec->vDD = doubleParameter(j[power]["vdd"], "vdd");
|
|
|
|
|
memSpec->iDD02 = doubleParameter(j[power]["idd02"], "idd02");
|
|
|
|
|
memSpec->iDD2P0 = doubleParameter(j[power]["idd2p0"], "idd2p0");
|
|
|
|
|
memSpec->iDD2P1 = doubleParameter(j[power]["idd2p1"], "idd2p1");
|
|
|
|
|
memSpec->iDD3P0 = doubleParameter(j[power]["idd3p0"], "idd3p0");
|
|
|
|
|
memSpec->iDD3P1 = doubleParameter(j[power]["idd3p1"], "idd3p1");
|
|
|
|
|
memSpec->iDD62 = doubleParameter(j[power]["idd62"], "idd62");
|
|
|
|
|
memSpec->vDD2 = doubleParameter(j[power]["vdd2"], "vdd2");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadLPDDR4(Configuration &config, XMLElement *xmlSpec)
|
|
|
|
|
void ConfigurationLoader::loadLPDDR4(Configuration &config, json::object_t *jsonSpec)
|
|
|
|
|
{
|
|
|
|
|
MemSpecLPDDR4 *memSpec = dynamic_cast<MemSpecLPDDR4 *>(config.memSpec);
|
|
|
|
|
if (memSpec == nullptr)
|
|
|
|
|
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
|
|
|
|
json j = *jsonSpec;
|
|
|
|
|
|
|
|
|
|
// MemArchitecture:
|
|
|
|
|
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
|
|
|
|
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
|
|
|
|
std::string arch = "memarchitecturespec";
|
|
|
|
|
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"],"nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = uIntParameter(j[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
|
|
|
|
|
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
|
|
|
|
memSpec->tREFIpb = memSpec->tCK * queryUIntParameter(timings, "REFIPB");
|
|
|
|
|
memSpec->tRFCab = memSpec->tCK * queryUIntParameter(timings, "RFCAB");
|
|
|
|
|
memSpec->tRFCpb = memSpec->tCK * queryUIntParameter(timings, "RFCPB");
|
|
|
|
|
memSpec->tRPab = memSpec->tCK * queryUIntParameter(timings, "RPAB");
|
|
|
|
|
memSpec->tRPpb = memSpec->tCK * queryUIntParameter(timings, "RPPB");
|
|
|
|
|
memSpec->tPPD = memSpec->tCK * queryUIntParameter(timings, "PPD");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
|
|
|
|
memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
|
|
|
|
memSpec->tRRD = memSpec->tCK * queryUIntParameter(timings, "RRD");
|
|
|
|
|
memSpec->tCCD = memSpec->tCK * queryUIntParameter(timings, "CCD");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
|
|
|
|
memSpec->tRPST = memSpec->tCK * queryUIntParameter(timings, "RPST");
|
|
|
|
|
memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
|
|
|
|
memSpec->tDQSS = memSpec->tCK * queryUIntParameter(timings, "DQSS");
|
|
|
|
|
memSpec->tDQS2DQ = memSpec->tCK * queryUIntParameter(timings, "DQS2DQ");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
|
|
|
|
memSpec->tWPRE = memSpec->tCK * queryUIntParameter(timings, "WPRE");
|
|
|
|
|
memSpec->tWTR = memSpec->tCK * queryUIntParameter(timings, "WTR");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
|
|
|
|
memSpec->tSR = memSpec->tCK * queryUIntParameter(timings, "SR");
|
|
|
|
|
memSpec->tXSR = memSpec->tCK * queryUIntParameter(timings, "XSR");
|
|
|
|
|
memSpec->tESCKE = memSpec->tCK * queryUIntParameter(timings, "ESCKE");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
|
|
|
|
memSpec->tCMDCKE = memSpec->tCK * queryUIntParameter(timings, "CMDCKE");
|
|
|
|
|
std::string timings = "memtimingspec";
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
|
|
|
|
|
memSpec->tREFIpb = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
|
|
|
|
|
memSpec->tRFCab = memSpec->tCK * uIntParameter(j[timings]["RFCAB"], "RFCAB");
|
|
|
|
|
memSpec->tRFCpb = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
|
|
|
|
|
memSpec->tRPab = memSpec->tCK * uIntParameter(j[timings]["RPAB"], "RPAB");
|
|
|
|
|
memSpec->tRPpb = memSpec->tCK * uIntParameter(j[timings]["RPPB"], "RPPB");
|
|
|
|
|
memSpec->tPPD = memSpec->tCK * uIntParameter(j[timings]["PPD"], "PPD");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
|
|
|
|
|
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
|
|
|
|
|
memSpec->tRRD = memSpec->tCK * uIntParameter(j[timings]["RRD"], "RRD");
|
|
|
|
|
memSpec->tCCD = memSpec->tCK * uIntParameter(j[timings]["CCD"], "CCD");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
|
|
|
|
|
memSpec->tRPST = memSpec->tCK * uIntParameter(j[timings]["RPST"], "RPST");
|
|
|
|
|
memSpec->tDQSCK = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
|
|
|
|
|
memSpec->tDQSS = memSpec->tCK * uIntParameter(j[timings]["DQSS"], "DQSS");
|
|
|
|
|
memSpec->tDQS2DQ = memSpec->tCK * uIntParameter(j[timings]["DQS2DQ"], "DQS2DQ");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
|
|
|
|
|
memSpec->tWPRE = memSpec->tCK * uIntParameter(j[timings]["WPRE"], "WPRE");
|
|
|
|
|
memSpec->tWTR = memSpec->tCK * uIntParameter(j[timings]["WTR"], "WTR");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
|
|
|
|
|
memSpec->tSR = memSpec->tCK * uIntParameter(j[timings]["SR"], "SR");
|
|
|
|
|
memSpec->tXSR = memSpec->tCK * uIntParameter(j[timings]["XSR"], "XSR");
|
|
|
|
|
memSpec->tESCKE = memSpec->tCK * uIntParameter(j[timings]["ESCKE"], "ESCKE");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
|
|
|
|
|
memSpec->tCMDCKE = memSpec->tCK * uIntParameter(j[timings]["CMDCKE"], "CMDCKE");
|
|
|
|
|
|
|
|
|
|
// Currents and voltages
|
|
|
|
|
// TODO: to be completed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadWideIO(Configuration &config, XMLElement *xmlSpec)
|
|
|
|
|
void ConfigurationLoader::loadWideIO(Configuration &config, json::object_t *jsonSpec)
|
|
|
|
|
{
|
|
|
|
|
MemSpecWideIO *memSpec = dynamic_cast<MemSpecWideIO *>(config.memSpec);
|
|
|
|
|
if (memSpec == nullptr)
|
|
|
|
|
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
|
|
|
|
json j = *jsonSpec;
|
|
|
|
|
|
|
|
|
|
// MemArchitecture
|
|
|
|
|
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
|
|
|
|
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
|
|
|
|
|
|
|
|
|
std::string arch = "memarchitecturespec";
|
|
|
|
|
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"], "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = uIntParameter(j[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
|
|
|
|
|
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
|
|
|
|
memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR");
|
|
|
|
|
memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
|
|
|
|
|
memSpec->tAC = memSpec->tCK * queryUIntParameter(timings, "AC");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
|
|
|
|
memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
|
|
|
|
memSpec->tCCD_R = memSpec->tCK * queryUIntParameter(timings, "CCD_R");
|
|
|
|
|
memSpec->tCCD_W = memSpec->tCK * queryUIntParameter(timings, "CCD_W");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
|
|
|
|
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
|
|
|
|
memSpec->tRRD = memSpec->tCK * queryUIntParameter(timings, "RRD");
|
|
|
|
|
memSpec->tTAW = memSpec->tCK * queryUIntParameter(timings, "TAW");
|
|
|
|
|
memSpec->tWTR = memSpec->tCK * queryUIntParameter(timings, "WTR");
|
|
|
|
|
std::string timings = "memtimingspec";
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
|
|
|
|
|
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
|
|
|
|
|
memSpec->tDQSCK = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
|
|
|
|
|
memSpec->tAC = memSpec->tCK * uIntParameter(j[timings]["AC"], "AC");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
|
|
|
|
|
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
|
|
|
|
|
memSpec->tCCD_R = memSpec->tCK * uIntParameter(j[timings]["CCD_R"], "CCD_R");
|
|
|
|
|
memSpec->tCCD_W = memSpec->tCK * uIntParameter(j[timings]["CCD_W"], "CCD_W");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
|
|
|
|
|
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
|
|
|
|
|
memSpec->tRRD = memSpec->tCK * uIntParameter(j[timings]["RRD"], "RRD");
|
|
|
|
|
memSpec->tTAW = memSpec->tCK * uIntParameter(j[timings]["TAW"], "TAW");
|
|
|
|
|
memSpec->tWTR = memSpec->tCK * uIntParameter(j[timings]["WTR"], "WTR");
|
|
|
|
|
|
|
|
|
|
// Currents and voltages
|
|
|
|
|
XMLElement *powers = xmlSpec->FirstChildElement("mempowerspec");
|
|
|
|
|
memSpec->iDD0 = queryDoubleParameter(powers, "idd0");
|
|
|
|
|
memSpec->iDD2N = queryDoubleParameter(powers, "idd2n");
|
|
|
|
|
memSpec->iDD3N = queryDoubleParameter(powers, "idd3n");
|
|
|
|
|
memSpec->iDD4R = queryDoubleParameter(powers, "idd4r");
|
|
|
|
|
memSpec->iDD4W = queryDoubleParameter(powers, "idd4w");
|
|
|
|
|
memSpec->iDD5 = queryDoubleParameter(powers, "idd5");
|
|
|
|
|
memSpec->iDD6 = queryDoubleParameter(powers, "idd6");
|
|
|
|
|
memSpec->vDD = queryDoubleParameter(powers, "vdd");
|
|
|
|
|
memSpec->iDD02 = queryDoubleParameter(powers, "idd02");
|
|
|
|
|
memSpec->iDD2P0 = queryDoubleParameter(powers, "idd2p0");
|
|
|
|
|
memSpec->iDD2P02 = queryDoubleParameter(powers, "idd2p02");
|
|
|
|
|
memSpec->iDD2P1 = queryDoubleParameter(powers, "idd2p1");
|
|
|
|
|
memSpec->iDD2P12 = queryDoubleParameter(powers, "idd2p12");
|
|
|
|
|
memSpec->iDD2N2 = queryDoubleParameter(powers, "idd2n2");
|
|
|
|
|
memSpec->iDD3P0 = queryDoubleParameter(powers, "idd3p0");
|
|
|
|
|
memSpec->iDD3P02 = queryDoubleParameter(powers, "idd3p02");
|
|
|
|
|
memSpec->iDD3P1 = queryDoubleParameter(powers, "idd3p1");
|
|
|
|
|
memSpec->iDD3P12 = queryDoubleParameter(powers, "idd3p12");
|
|
|
|
|
memSpec->iDD3N2 = queryDoubleParameter(powers, "idd3n2");
|
|
|
|
|
memSpec->iDD4R2 = queryDoubleParameter(powers, "idd4r2");
|
|
|
|
|
memSpec->iDD4W2 = queryDoubleParameter(powers, "idd4w2");
|
|
|
|
|
memSpec->iDD52 = queryDoubleParameter(powers, "idd52");
|
|
|
|
|
memSpec->iDD62 = queryDoubleParameter(powers, "idd62");
|
|
|
|
|
memSpec->vDD2 = queryDoubleParameter(powers, "vdd2");
|
|
|
|
|
std::string power = "mempowerspec";
|
|
|
|
|
memSpec->iDD0 = doubleParameter(j[power]["idd0"], "idd0");
|
|
|
|
|
memSpec->iDD2N = doubleParameter(j[power]["idd2n"], "idd2n");
|
|
|
|
|
memSpec->iDD3N = doubleParameter(j[power]["idd3n"], "idd3n");
|
|
|
|
|
memSpec->iDD4R = doubleParameter(j[power]["idd4r"], "idd4r");
|
|
|
|
|
memSpec->iDD4W = doubleParameter(j[power]["idd4w"], "idd4w");
|
|
|
|
|
memSpec->iDD5 = doubleParameter(j[power]["idd5"], "idd5");
|
|
|
|
|
memSpec->iDD6 = doubleParameter(j[power]["idd6"], "idd6");
|
|
|
|
|
memSpec->vDD = doubleParameter(j[power]["vdd"], "vdd");
|
|
|
|
|
memSpec->iDD02 = doubleParameter(j[power]["idd02"], "idd02");
|
|
|
|
|
memSpec->iDD2P0 = doubleParameter(j[power]["idd2p0"], "idd2p0");
|
|
|
|
|
memSpec->iDD2P02 = doubleParameter(j[power]["idd2p02"], "idd2p02");
|
|
|
|
|
memSpec->iDD2P1 = doubleParameter(j[power]["idd2p1"], "idd2p1");
|
|
|
|
|
memSpec->iDD2P12 = doubleParameter(j[power]["idd2p12"], "idd2p12");
|
|
|
|
|
memSpec->iDD2N2 = doubleParameter(j[power]["idd2n2"], "idd2n2");
|
|
|
|
|
memSpec->iDD3P0 = doubleParameter(j[power]["idd3p0"], "idd3p0");
|
|
|
|
|
memSpec->iDD3P02 = doubleParameter(j[power]["idd3p02"], "idd3p02");
|
|
|
|
|
memSpec->iDD3P1 = doubleParameter(j[power]["idd3p1"], "idd3p1");
|
|
|
|
|
memSpec->iDD3P12 = doubleParameter(j[power]["idd3p12"], "idd3p12");
|
|
|
|
|
memSpec->iDD3N2 = doubleParameter(j[power]["idd3n2"], "idd3n2");
|
|
|
|
|
memSpec->iDD4R2 = doubleParameter(j[power]["idd4r2"], "idd4r2");
|
|
|
|
|
memSpec->iDD4W2 = doubleParameter(j[power]["idd4w2"], "idd4w2");
|
|
|
|
|
memSpec->iDD52 = doubleParameter(j[power]["idd52"], "idd52");
|
|
|
|
|
memSpec->iDD62 = doubleParameter(j[power]["idd62"], "idd62");
|
|
|
|
|
memSpec->vDD2 = doubleParameter(j[power]["vdd2"], "vdd2");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadWideIO2(Configuration &config, XMLElement *xmlSpec)
|
|
|
|
|
void ConfigurationLoader::loadWideIO2(Configuration &config, json::object_t *jsonSpec)
|
|
|
|
|
{
|
|
|
|
|
MemSpecWideIO2 *memSpec = dynamic_cast<MemSpecWideIO2 *>(config.memSpec);
|
|
|
|
|
if (memSpec == nullptr)
|
|
|
|
|
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
|
|
|
|
json j = *jsonSpec;
|
|
|
|
|
|
|
|
|
|
// MemArchitecture
|
|
|
|
|
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
|
|
|
|
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
|
|
|
|
|
|
|
|
|
std::string arch = "memarchitecturespec";
|
|
|
|
|
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"], "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = uIntParameter(j[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
|
|
|
|
|
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
|
|
|
|
memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
|
|
|
|
|
memSpec->tDQSS = memSpec->tCK * queryUIntParameter(timings, "DQSS");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
|
|
|
|
memSpec->tRCpb = memSpec->tCK * queryUIntParameter(timings, "RCPB");
|
|
|
|
|
memSpec->tRCab = memSpec->tCK * queryUIntParameter(timings, "RCAB");
|
|
|
|
|
memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR");
|
|
|
|
|
memSpec->tXSR = memSpec->tCK * queryUIntParameter(timings, "XSR");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
|
|
|
|
memSpec->tCCD = memSpec->tCK * queryUIntParameter(timings, "CCD");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
|
|
|
|
memSpec->tRCD = memSpec->tCK * queryUIntParameter(timings, "RCD");
|
|
|
|
|
memSpec->tRPpb = memSpec->tCK * queryUIntParameter(timings, "RPPB");
|
|
|
|
|
memSpec->tRPab = memSpec->tCK * queryUIntParameter(timings, "RPAB");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
|
|
|
|
memSpec->tWTR = memSpec->tCK * queryUIntParameter(timings, "WTR");
|
|
|
|
|
memSpec->tRRD = memSpec->tCK * queryUIntParameter(timings, "RRD");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
|
|
|
|
memSpec->tREFIpb = memSpec->tCK * queryUIntParameter(timings, "REFIPB");
|
|
|
|
|
memSpec->tRFCab = memSpec->tCK * queryUIntParameter(timings, "RFCAB");
|
|
|
|
|
memSpec->tRFCpb = memSpec->tCK * queryUIntParameter(timings, "RFCPB");
|
|
|
|
|
std::string timings = "memtimingspec";
|
|
|
|
|
memSpec->tDQSCK = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
|
|
|
|
|
memSpec->tDQSS = memSpec->tCK * uIntParameter(j[timings]["DQSS"], "DQSS");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
|
|
|
|
|
memSpec->tRCpb = memSpec->tCK * uIntParameter(j[timings]["RCPB"], "RCPB");
|
|
|
|
|
memSpec->tRCab = memSpec->tCK * uIntParameter(j[timings]["RCAB"], "RCAB");
|
|
|
|
|
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
|
|
|
|
|
memSpec->tXSR = memSpec->tCK * uIntParameter(j[timings]["XSR"], "XSR");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
|
|
|
|
|
memSpec->tCCD = memSpec->tCK * uIntParameter(j[timings]["CCD"], "CCD");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
|
|
|
|
|
memSpec->tRCD = memSpec->tCK * uIntParameter(j[timings]["RCD"], "RCD");
|
|
|
|
|
memSpec->tRPpb = memSpec->tCK * uIntParameter(j[timings]["RPPB"], "RPPB");
|
|
|
|
|
memSpec->tRPab = memSpec->tCK * uIntParameter(j[timings]["RPAB"], "RPAB");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
|
|
|
|
|
memSpec->tWTR = memSpec->tCK * uIntParameter(j[timings]["WTR"], "WTR");
|
|
|
|
|
memSpec->tRRD = memSpec->tCK * uIntParameter(j[timings]["RRD"], "RRD");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
|
|
|
|
|
memSpec->tREFIpb = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
|
|
|
|
|
memSpec->tRFCab = memSpec->tCK * uIntParameter(j[timings]["RFCAB"], "RFCAB");
|
|
|
|
|
memSpec->tRFCpb = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
|
|
|
|
|
|
|
|
|
|
// Currents and voltages
|
|
|
|
|
// TODO: to be completed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadHBM2(Configuration &config, XMLElement *xmlSpec)
|
|
|
|
|
void ConfigurationLoader::loadHBM2(Configuration &config, json::object_t *jsonSpec)
|
|
|
|
|
{
|
|
|
|
|
MemSpecHBM2 *memSpec = dynamic_cast<MemSpecHBM2 *>(config.memSpec);
|
|
|
|
|
if (memSpec == nullptr)
|
|
|
|
|
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
|
|
|
|
json j = *jsonSpec;
|
|
|
|
|
|
|
|
|
|
// MemArchitecture
|
|
|
|
|
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
|
|
|
|
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
|
|
|
|
memSpec->groupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
|
|
|
|
|
|
|
|
|
std::string arch = "memarchitecturespec";
|
|
|
|
|
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"], "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = uIntParameter(j[arch]["nbrOfBanks"], "nbrOfBanks");
|
|
|
|
|
memSpec->groupsPerRank = uIntParameter(j[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
|
|
|
|
|
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
|
|
|
|
memSpec->tDQSCK = memSpec->tCK * queryUIntParameter(timings, "DQSCK");
|
|
|
|
|
// memSpec->tDQSQ = memSpec->tCK * queryUIntParameter(timings, "DQSQ");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
|
|
|
|
memSpec->tRCDRD = memSpec->tCK * queryUIntParameter(timings, "RCDRD");
|
|
|
|
|
memSpec->tRCDWR = memSpec->tCK * queryUIntParameter(timings, "RCDWR");
|
|
|
|
|
memSpec->tRRDL = memSpec->tCK * queryUIntParameter(timings, "RRDL");
|
|
|
|
|
memSpec->tRRDS = memSpec->tCK * queryUIntParameter(timings, "RRDS");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
|
|
|
|
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
|
|
|
|
memSpec->tPL = memSpec->tCK * queryUIntParameter(timings, "PL");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
|
|
|
|
memSpec->tCCDL = memSpec->tCK * queryUIntParameter(timings, "CCDL");
|
|
|
|
|
memSpec->tCCDS = memSpec->tCK * queryUIntParameter(timings, "CCDS");
|
|
|
|
|
// memSpec->tCCDR = memSpec->tCK * queryUIntParameter(timings, "CCDR");
|
|
|
|
|
memSpec->tWTRL = memSpec->tCK * queryUIntParameter(timings, "WTRL");
|
|
|
|
|
memSpec->tWTRS = memSpec->tCK * queryUIntParameter(timings, "WTRS");
|
|
|
|
|
memSpec->tRTW = memSpec->tCK * queryUIntParameter(timings, "RTW");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
|
|
|
|
std::string timings = "memtimingspec";
|
|
|
|
|
memSpec->tDQSCK = memSpec->tCK * uIntParameter(j[timings]["DQSCK"], "DQSCK");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
|
|
|
|
|
memSpec->tRCDRD = memSpec->tCK * uIntParameter(j[timings]["RCDRD"], "RCDRD");
|
|
|
|
|
memSpec->tRCDWR = memSpec->tCK * uIntParameter(j[timings]["RCDWR"], "RCDWR");
|
|
|
|
|
memSpec->tRRDL = memSpec->tCK * uIntParameter(j[timings]["RRDL"], "RRDL");
|
|
|
|
|
memSpec->tRRDS = memSpec->tCK * uIntParameter(j[timings]["RRDS"], "RRDS");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
|
|
|
|
|
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
|
|
|
|
|
memSpec->tPL = memSpec->tCK * uIntParameter(j[timings]["PL"], "PL");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
|
|
|
|
|
memSpec->tCCDL = memSpec->tCK * uIntParameter(j[timings]["CCDL"], "CCDL");
|
|
|
|
|
memSpec->tCCDS = memSpec->tCK * uIntParameter(j[timings]["CCDS"], "CCDS");
|
|
|
|
|
memSpec->tWTRL = memSpec->tCK * uIntParameter(j[timings]["WTRL"], "WTRL");
|
|
|
|
|
memSpec->tWTRS = memSpec->tCK * uIntParameter(j[timings]["WTRS"], "WTRS");
|
|
|
|
|
memSpec->tRTW = memSpec->tCK * uIntParameter(j[timings]["RTW"], "RTW");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
|
|
|
|
|
memSpec->tPD = memSpec->tCKE;
|
|
|
|
|
memSpec->tRDPDE = memSpec->tRL + memSpec->tPL
|
|
|
|
|
+ (memSpec->burstLength / memSpec->dataRate + 1) * memSpec->tCK;
|
|
|
|
|
@@ -573,192 +574,198 @@ void ConfigurationLoader::loadHBM2(Configuration &config, XMLElement *xmlSpec)
|
|
|
|
|
memSpec->tCKESR = memSpec->tCKE + memSpec->tCK;
|
|
|
|
|
memSpec->tRDSRE = memSpec->tRL + memSpec->tPL
|
|
|
|
|
+ (memSpec->burstLength / memSpec->dataRate + 1) * memSpec->tCK;
|
|
|
|
|
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
|
|
|
|
memSpec->tRFCSB = memSpec->tCK * queryUIntParameter(timings, "RFCSB");
|
|
|
|
|
memSpec->tRREFD = memSpec->tCK * queryUIntParameter(timings, "RREFD");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
|
|
|
|
memSpec->tREFISB = memSpec->tCK * queryUIntParameter(timings, "REFISB");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
|
|
|
|
|
memSpec->tRFCSB = memSpec->tCK * uIntParameter(j[timings]["RFCSB"], "RFCSB");
|
|
|
|
|
memSpec->tRREFD = memSpec->tCK * uIntParameter(j[timings]["RREFD"], "RREFD");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
|
|
|
|
|
memSpec->tREFISB = memSpec->tCK * uIntParameter(j[timings]["REFISB"], "REFISB");
|
|
|
|
|
|
|
|
|
|
// Currents and voltages
|
|
|
|
|
// TODO: to be completed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadGDDR5(Configuration &config, XMLElement *xmlSpec)
|
|
|
|
|
void ConfigurationLoader::loadGDDR5(Configuration &config, json::object_t *jsonSpec)
|
|
|
|
|
{
|
|
|
|
|
MemSpecGDDR5 *memSpec = dynamic_cast<MemSpecGDDR5 *>(config.memSpec);
|
|
|
|
|
if (memSpec == nullptr)
|
|
|
|
|
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
|
|
|
|
json j = *jsonSpec;
|
|
|
|
|
|
|
|
|
|
// MemArchitecture
|
|
|
|
|
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
|
|
|
|
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
|
|
|
|
memSpec->groupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
|
|
|
|
|
|
|
|
|
std::string arch = "memarchitecturespec";
|
|
|
|
|
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"], "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = uIntParameter(j[arch]["nbrOfBanks"], "nbrOfBanks");
|
|
|
|
|
memSpec->groupsPerRank = uIntParameter(j[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
|
|
|
|
|
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
|
|
|
|
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
|
|
|
|
memSpec->tRCDRD = memSpec->tCK * queryUIntParameter(timings, "RCDRD");
|
|
|
|
|
memSpec->tRCDWR = memSpec->tCK * queryUIntParameter(timings, "RCDWR");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
|
|
|
|
memSpec->tRRDS = memSpec->tCK * queryUIntParameter(timings, "RRDS");
|
|
|
|
|
memSpec->tRRDL = memSpec->tCK * queryUIntParameter(timings, "RRDL");
|
|
|
|
|
memSpec->tCCDS = memSpec->tCK * queryUIntParameter(timings, "CCDS");
|
|
|
|
|
memSpec->tCCDL = memSpec->tCK * queryUIntParameter(timings, "CCDL");
|
|
|
|
|
memSpec->tCL = memSpec->tCK * queryUIntParameter(timings, "CL");
|
|
|
|
|
memSpec->tWCK2CKPIN = memSpec->tCK * queryUIntParameter(timings, "WCK2CKPIN");
|
|
|
|
|
memSpec->tWCK2CK = memSpec->tCK * queryUIntParameter(timings, "WCK2CK");
|
|
|
|
|
memSpec->tWCK2DQO = memSpec->tCK * queryUIntParameter(timings, "WCK2DQO");
|
|
|
|
|
memSpec->tRTW = memSpec->tCK * queryUIntParameter(timings, "RTW");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
|
|
|
|
memSpec->tWCK2DQI = memSpec->tCK * queryUIntParameter(timings, "WCK2DQI");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
|
|
|
|
memSpec->tWTRS = memSpec->tCK * queryUIntParameter(timings, "WTRS");
|
|
|
|
|
memSpec->tWTRL = memSpec->tCK * queryUIntParameter(timings, "WTRL");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
|
|
|
|
std::string timings = "memtimingspec";
|
|
|
|
|
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
|
|
|
|
|
memSpec->tRCDRD = memSpec->tCK * uIntParameter(j[timings]["RCDRD"], "RCDRD");
|
|
|
|
|
memSpec->tRCDWR = memSpec->tCK * uIntParameter(j[timings]["RCDWR"], "RCDWR");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
|
|
|
|
|
memSpec->tRRDS = memSpec->tCK * uIntParameter(j[timings]["RRDS"], "RRDS");
|
|
|
|
|
memSpec->tRRDL = memSpec->tCK * uIntParameter(j[timings]["RRDL"], "RRDL");
|
|
|
|
|
memSpec->tCCDS = memSpec->tCK * uIntParameter(j[timings]["CCDS"], "CCDS");
|
|
|
|
|
memSpec->tCCDL = memSpec->tCK * uIntParameter(j[timings]["CCDL"], "CCDL");
|
|
|
|
|
memSpec->tCL = memSpec->tCK * uIntParameter(j[timings]["CL"], "CL");
|
|
|
|
|
memSpec->tWCK2CKPIN = memSpec->tCK * uIntParameter(j[timings]["WCK2CKPIN"], "WCK2CKPIN");
|
|
|
|
|
memSpec->tWCK2CK = memSpec->tCK * uIntParameter(j[timings]["WCK2CK"], "WCK2CK");
|
|
|
|
|
memSpec->tWCK2DQO = memSpec->tCK * uIntParameter(j[timings]["WCK2DQO"], "WCK2DQO");
|
|
|
|
|
memSpec->tRTW = memSpec->tCK * uIntParameter(j[timings]["RTW"], "RTW");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
|
|
|
|
|
memSpec->tWCK2DQI = memSpec->tCK * uIntParameter(j[timings]["WCK2DQI"], "WCK2DQI");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
|
|
|
|
|
memSpec->tWTRS = memSpec->tCK * uIntParameter(j[timings]["WTRS"], "WTRS");
|
|
|
|
|
memSpec->tWTRL = memSpec->tCK * uIntParameter(j[timings]["WTRL"], "WTRL");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
|
|
|
|
|
memSpec->tPD = memSpec->tCKE;
|
|
|
|
|
memSpec->tXPN = memSpec->tCK * queryUIntParameter(timings, "XPN");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
|
|
|
|
memSpec->tREFIPB = memSpec->tCK * queryUIntParameter(timings, "REFIPB");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
|
|
|
|
memSpec->tRFCPB = memSpec->tCK * queryUIntParameter(timings, "RFCPB");
|
|
|
|
|
memSpec->tRREFD = memSpec->tCK * queryUIntParameter(timings, "RREFD");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
|
|
|
|
memSpec->t32AW = memSpec->tCK * queryUIntParameter(timings, "32AW");
|
|
|
|
|
memSpec->tXPN = memSpec->tCK * uIntParameter(j[timings]["XPN"], "XPN");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
|
|
|
|
|
memSpec->tREFIPB = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
|
|
|
|
|
memSpec->tRFCPB = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
|
|
|
|
|
memSpec->tRREFD = memSpec->tCK * uIntParameter(j[timings]["RREFD"], "RREFD");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
|
|
|
|
|
memSpec->t32AW = memSpec->tCK * uIntParameter(j[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 * queryUIntParameter(timings, "PPD");
|
|
|
|
|
memSpec->tLK = memSpec->tCK * queryUIntParameter(timings, "LK");
|
|
|
|
|
memSpec->tPPD = memSpec->tCK * uIntParameter(j[timings]["PPD"], "PPD");
|
|
|
|
|
memSpec->tLK = memSpec->tCK * uIntParameter(j[timings]["LK"], "LK");
|
|
|
|
|
|
|
|
|
|
// Currents and voltages
|
|
|
|
|
// TODO: to be completed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadGDDR5X(Configuration &config, XMLElement *xmlSpec)
|
|
|
|
|
void ConfigurationLoader::loadGDDR5X(Configuration &config, json::object_t *jsonSpec)
|
|
|
|
|
{
|
|
|
|
|
MemSpecGDDR5X *memSpec = dynamic_cast<MemSpecGDDR5X *>(config.memSpec);
|
|
|
|
|
if (memSpec == nullptr)
|
|
|
|
|
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
|
|
|
|
json j = *jsonSpec;
|
|
|
|
|
|
|
|
|
|
// MemArchitecture
|
|
|
|
|
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
|
|
|
|
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
|
|
|
|
memSpec->groupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
|
|
|
|
|
|
|
|
|
std::string arch = "memarchitecturespec";
|
|
|
|
|
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"], "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = uIntParameter(j[arch]["nbrOfBanks"], "nbrOfBanks");
|
|
|
|
|
memSpec->groupsPerRank = uIntParameter(j[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
|
|
|
|
|
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
|
|
|
|
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
|
|
|
|
memSpec->tRCDRD = memSpec->tCK * queryUIntParameter(timings, "RCDRD");
|
|
|
|
|
memSpec->tRCDWR = memSpec->tCK * queryUIntParameter(timings, "RCDWR");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
|
|
|
|
memSpec->tRRDS = memSpec->tCK * queryUIntParameter(timings, "RRDS");
|
|
|
|
|
memSpec->tRRDL = memSpec->tCK * queryUIntParameter(timings, "RRDL");
|
|
|
|
|
memSpec->tCCDS = memSpec->tCK * queryUIntParameter(timings, "CCDS");
|
|
|
|
|
memSpec->tCCDL = memSpec->tCK * queryUIntParameter(timings, "CCDL");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
|
|
|
|
memSpec->tWCK2CKPIN = memSpec->tCK * queryUIntParameter(timings, "WCK2CKPIN");
|
|
|
|
|
memSpec->tWCK2CK = memSpec->tCK * queryUIntParameter(timings, "WCK2CK");
|
|
|
|
|
memSpec->tWCK2DQO = memSpec->tCK * queryUIntParameter(timings, "WCK2DQO");
|
|
|
|
|
memSpec->tRTW = memSpec->tCK * queryUIntParameter(timings, "RTW");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
|
|
|
|
memSpec->tWCK2DQI = memSpec->tCK * queryUIntParameter(timings, "WCK2DQI");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
|
|
|
|
memSpec->tWTRS = memSpec->tCK * queryUIntParameter(timings, "WTRS");
|
|
|
|
|
memSpec->tWTRL = memSpec->tCK * queryUIntParameter(timings, "WTRL");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
|
|
|
|
std::string timings = "memtimingspec";
|
|
|
|
|
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
|
|
|
|
|
memSpec->tRCDRD = memSpec->tCK * uIntParameter(j[timings]["RCDRD"], "RCDRD");
|
|
|
|
|
memSpec->tRCDWR = memSpec->tCK * uIntParameter(j[timings]["RCDWR"], "RCDWR");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
|
|
|
|
|
memSpec->tRRDS = memSpec->tCK * uIntParameter(j[timings]["RRDS"], "RRDS");
|
|
|
|
|
memSpec->tRRDL = memSpec->tCK * uIntParameter(j[timings]["RRDL"], "RRDL");
|
|
|
|
|
memSpec->tCCDS = memSpec->tCK * uIntParameter(j[timings]["CCDS"], "CCDS");
|
|
|
|
|
memSpec->tCCDL = memSpec->tCK * uIntParameter(j[timings]["CCDL"], "CCDL");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
|
|
|
|
|
memSpec->tWCK2CKPIN = memSpec->tCK * uIntParameter(j[timings]["WCK2CKPIN"], "WCK2CKPIN");
|
|
|
|
|
memSpec->tWCK2CK = memSpec->tCK * uIntParameter(j[timings]["WCK2CK"], "WCK2CK");
|
|
|
|
|
memSpec->tWCK2DQO = memSpec->tCK * uIntParameter(j[timings]["WCK2DQO"], "WCK2DQO");
|
|
|
|
|
memSpec->tRTW = memSpec->tCK * uIntParameter(j[timings]["RTW"], "RTW");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
|
|
|
|
|
memSpec->tWCK2DQI = memSpec->tCK * uIntParameter(j[timings]["WCK2DQI"], "WCK2DQI");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
|
|
|
|
|
memSpec->tWTRS = memSpec->tCK * uIntParameter(j[timings]["WTRS"], "WTRS");
|
|
|
|
|
memSpec->tWTRL = memSpec->tCK * uIntParameter(j[timings]["WTRL"], "WTRL");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
|
|
|
|
|
memSpec->tPD = memSpec->tCKE;
|
|
|
|
|
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
|
|
|
|
memSpec->tREFIPB = memSpec->tCK * queryUIntParameter(timings, "REFIPB");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
|
|
|
|
memSpec->tRFCPB = memSpec->tCK * queryUIntParameter(timings, "RFCPB");
|
|
|
|
|
memSpec->tRREFD = memSpec->tCK * queryUIntParameter(timings, "RREFD");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
|
|
|
|
memSpec->t32AW = memSpec->tCK * queryUIntParameter(timings, "32AW");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
|
|
|
|
|
memSpec->tREFIPB = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
|
|
|
|
|
memSpec->tRFCPB = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
|
|
|
|
|
memSpec->tRREFD = memSpec->tCK * uIntParameter(j[timings]["RREFD"], "RREFD");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * uIntParameter(j[timings]["FAW"], "FAW");
|
|
|
|
|
memSpec->t32AW = memSpec->tCK * uIntParameter(j[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 * queryUIntParameter(timings, "PPD");
|
|
|
|
|
memSpec->tLK = memSpec->tCK * queryUIntParameter(timings, "LK");
|
|
|
|
|
memSpec->tPPD = memSpec->tCK * uIntParameter(j[timings]["PPD"], "PPD");
|
|
|
|
|
memSpec->tLK = memSpec->tCK * uIntParameter(j[timings]["LK"], "LK");
|
|
|
|
|
|
|
|
|
|
// Currents and voltages
|
|
|
|
|
// TODO: to be completed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ConfigurationLoader::loadGDDR6(Configuration &config, XMLElement *xmlSpec)
|
|
|
|
|
void ConfigurationLoader::loadGDDR6(Configuration &config, json::object_t *jsonSpec)
|
|
|
|
|
{
|
|
|
|
|
MemSpecGDDR6 *memSpec = dynamic_cast<MemSpecGDDR6 *>(config.memSpec);
|
|
|
|
|
if (memSpec == nullptr)
|
|
|
|
|
SC_REPORT_FATAL("ConfigurationLoader", "Wrong MemSpec chosen");
|
|
|
|
|
json j = *jsonSpec;
|
|
|
|
|
|
|
|
|
|
// MemArchitecture
|
|
|
|
|
XMLElement *architecture = xmlSpec->FirstChildElement("memarchitecturespec");
|
|
|
|
|
memSpec->numberOfRanks = queryUIntParameter(architecture, "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = queryUIntParameter(architecture, "nbrOfBanks");
|
|
|
|
|
memSpec->groupsPerRank = queryUIntParameter(architecture, "nbrOfBankGroups");
|
|
|
|
|
|
|
|
|
|
std::string arch = "memarchitecturespec";
|
|
|
|
|
memSpec->numberOfRanks = uIntParameter(j[arch]["nbrOfRanks"], "nbrOfRanks");
|
|
|
|
|
memSpec->banksPerRank = uIntParameter(j[arch]["nbrOfBanks"], "nbrOfBanks");
|
|
|
|
|
memSpec->groupsPerRank = uIntParameter(j[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
|
|
|
|
|
XMLElement *timings = xmlSpec->FirstChildElement("memtimingspec");
|
|
|
|
|
memSpec->tRP = memSpec->tCK * queryUIntParameter(timings, "RP");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * queryUIntParameter(timings, "RAS");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * queryUIntParameter(timings, "RC");
|
|
|
|
|
memSpec->tRCDRD = memSpec->tCK * queryUIntParameter(timings, "RCDRD");
|
|
|
|
|
memSpec->tRCDWR = memSpec->tCK * queryUIntParameter(timings, "RCDWR");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * queryUIntParameter(timings, "RTP");
|
|
|
|
|
memSpec->tRRDS = memSpec->tCK * queryUIntParameter(timings, "RRDS");
|
|
|
|
|
memSpec->tRRDL = memSpec->tCK * queryUIntParameter(timings, "RRDL");
|
|
|
|
|
memSpec->tCCDS = memSpec->tCK * queryUIntParameter(timings, "CCDS");
|
|
|
|
|
memSpec->tCCDL = memSpec->tCK * queryUIntParameter(timings, "CCDL");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * queryUIntParameter(timings, "RL");
|
|
|
|
|
memSpec->tWCK2CKPIN = memSpec->tCK * queryUIntParameter(timings, "WCK2CKPIN");
|
|
|
|
|
memSpec->tWCK2CK = memSpec->tCK * queryUIntParameter(timings, "WCK2CK");
|
|
|
|
|
memSpec->tWCK2DQO = memSpec->tCK * queryUIntParameter(timings, "WCK2DQO");
|
|
|
|
|
memSpec->tRTW = memSpec->tCK * queryUIntParameter(timings, "RTW");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * queryUIntParameter(timings, "WL");
|
|
|
|
|
memSpec->tWCK2DQI = memSpec->tCK * queryUIntParameter(timings, "WCK2DQI");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * queryUIntParameter(timings, "WR");
|
|
|
|
|
memSpec->tWTRS = memSpec->tCK * queryUIntParameter(timings, "WTRS");
|
|
|
|
|
memSpec->tWTRL = memSpec->tCK * queryUIntParameter(timings, "WTRL");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * queryUIntParameter(timings, "CKE");
|
|
|
|
|
std::string timings = "memtimingspec";
|
|
|
|
|
memSpec->tRP = memSpec->tCK * uIntParameter(j[timings]["RP"], "RP");
|
|
|
|
|
memSpec->tRAS = memSpec->tCK * uIntParameter(j[timings]["RAS"], "RAS");
|
|
|
|
|
memSpec->tRC = memSpec->tCK * uIntParameter(j[timings]["RC"], "RC");
|
|
|
|
|
memSpec->tRCDRD = memSpec->tCK * uIntParameter(j[timings]["RCDRD"], "RCDRD");
|
|
|
|
|
memSpec->tRCDWR = memSpec->tCK * uIntParameter(j[timings]["RCDWR"], "RCDWR");
|
|
|
|
|
memSpec->tRTP = memSpec->tCK * uIntParameter(j[timings]["RTP"], "RTP");
|
|
|
|
|
memSpec->tRRDS = memSpec->tCK * uIntParameter(j[timings]["RRDS"], "RRDS");
|
|
|
|
|
memSpec->tRRDL = memSpec->tCK * uIntParameter(j[timings]["RRDL"], "RRDL");
|
|
|
|
|
memSpec->tCCDS = memSpec->tCK * uIntParameter(j[timings]["CCDS"], "CCDS");
|
|
|
|
|
memSpec->tCCDL = memSpec->tCK * uIntParameter(j[timings]["CCDL"], "CCDL");
|
|
|
|
|
memSpec->tRL = memSpec->tCK * uIntParameter(j[timings]["RL"], "RL");
|
|
|
|
|
memSpec->tWCK2CKPIN = memSpec->tCK * uIntParameter(j[timings]["WCK2CKPIN"], "WCK2CKPIN");
|
|
|
|
|
memSpec->tWCK2CK = memSpec->tCK * uIntParameter(j[timings]["WCK2CK"], "WCK2CK");
|
|
|
|
|
memSpec->tWCK2DQO = memSpec->tCK * uIntParameter(j[timings]["WCK2DQO"], "WCK2DQO");
|
|
|
|
|
memSpec->tRTW = memSpec->tCK * uIntParameter(j[timings]["RTW"], "RTW");
|
|
|
|
|
memSpec->tWL = memSpec->tCK * uIntParameter(j[timings]["WL"], "WL");
|
|
|
|
|
memSpec->tWCK2DQI = memSpec->tCK * uIntParameter(j[timings]["WCK2DQI"], "WCK2DQI");
|
|
|
|
|
memSpec->tWR = memSpec->tCK * uIntParameter(j[timings]["WR"], "WR");
|
|
|
|
|
memSpec->tWTRS = memSpec->tCK * uIntParameter(j[timings]["WTRS"], "WTRS");
|
|
|
|
|
memSpec->tWTRL = memSpec->tCK * uIntParameter(j[timings]["WTRL"], "WTRL");
|
|
|
|
|
memSpec->tCKE = memSpec->tCK * uIntParameter(j[timings]["CKE"], "CKE");
|
|
|
|
|
memSpec->tPD = memSpec->tCKE;
|
|
|
|
|
memSpec->tCKESR = memSpec->tCK * queryUIntParameter(timings, "CKESR");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * queryUIntParameter(timings, "XP");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * queryUIntParameter(timings, "REFI");
|
|
|
|
|
memSpec->tREFIPB = memSpec->tCK * queryUIntParameter(timings, "REFIPB");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * queryUIntParameter(timings, "RFC");
|
|
|
|
|
memSpec->tRFCPB = memSpec->tCK * queryUIntParameter(timings, "RFCPB");
|
|
|
|
|
memSpec->tRREFD = memSpec->tCK * queryUIntParameter(timings, "RREFD");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * queryUIntParameter(timings, "XS");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * queryUIntParameter(timings, "FAW");
|
|
|
|
|
memSpec->tCKESR = memSpec->tCK * uIntParameter(j[timings]["CKESR"], "CKESR");
|
|
|
|
|
memSpec->tXP = memSpec->tCK * uIntParameter(j[timings]["XP"], "XP");
|
|
|
|
|
memSpec->tREFI = memSpec->tCK * uIntParameter(j[timings]["REFI"], "REFI");
|
|
|
|
|
memSpec->tREFIPB = memSpec->tCK * uIntParameter(j[timings]["REFIPB"], "REFIPB");
|
|
|
|
|
memSpec->tRFC = memSpec->tCK * uIntParameter(j[timings]["RFC"], "RFC");
|
|
|
|
|
memSpec->tRFCPB = memSpec->tCK * uIntParameter(j[timings]["RFCPB"], "RFCPB");
|
|
|
|
|
memSpec->tRREFD = memSpec->tCK * uIntParameter(j[timings]["RREFD"], "RREFD");
|
|
|
|
|
memSpec->tXS = memSpec->tCK * uIntParameter(j[timings]["XS"], "XS");
|
|
|
|
|
memSpec->tFAW = memSpec->tCK * uIntParameter(j[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 * queryUIntParameter(timings, "PPD");
|
|
|
|
|
memSpec->tLK = memSpec->tCK * queryUIntParameter(timings, "LK");
|
|
|
|
|
memSpec->tACTPDE = memSpec->tCK * queryUIntParameter(timings, "ACTPDE");
|
|
|
|
|
memSpec->tPREPDE = memSpec->tCK * queryUIntParameter(timings, "PREPDE");
|
|
|
|
|
memSpec->tREFPDE = memSpec->tCK * queryUIntParameter(timings, "REFPDE");
|
|
|
|
|
memSpec->tPPD = memSpec->tCK * uIntParameter(j[timings]["PPD"], "PPD");
|
|
|
|
|
memSpec->tLK = memSpec->tCK * uIntParameter(j[timings]["LK"], "LK");
|
|
|
|
|
memSpec->tACTPDE = memSpec->tCK * uIntParameter(j[timings]["ACTPDE"], "ACTPDE");
|
|
|
|
|
memSpec->tPREPDE = memSpec->tCK * uIntParameter(j[timings]["PREPDE"], "PREPDE");
|
|
|
|
|
memSpec->tREFPDE = memSpec->tCK * uIntParameter(j[timings]["REFPDE"], "REFPDE");
|
|
|
|
|
|
|
|
|
|
// Currents and voltages
|
|
|
|
|
// TODO: to be completed
|
|
|
|
|
|