181 lines
7.6 KiB
C++
181 lines
7.6 KiB
C++
/*
|
|
* MemSpecLoader.cpp
|
|
*
|
|
* Created on: Apr 7, 2014
|
|
* Author: jonny
|
|
*/
|
|
|
|
#include "MemSpecLoader.h"
|
|
#include "TimingConfiguration.h"
|
|
|
|
using namespace tinyxml2;
|
|
using namespace std;
|
|
|
|
namespace core {
|
|
|
|
void MemSpecLoader::loadConfiguration(Configuration& config, string memspecUri, string memconfigUri)
|
|
{
|
|
tinyxml2::XMLDocument doc;
|
|
|
|
loadXML(memspecUri, doc);
|
|
XMLElement* memspec = doc.FirstChildElement("memspec");
|
|
loadMemSpec(config, memspec);
|
|
|
|
loadXML(memconfigUri, doc);
|
|
XMLElement* memconfig = doc.FirstChildElement("memspec");
|
|
loadMemConfig(config, memconfig);
|
|
}
|
|
|
|
void MemSpecLoader::loadMemConfig(Configuration& config, XMLElement* memconfig)
|
|
{
|
|
//MemConfiguration
|
|
XMLElement* configuration = memconfig->FirstChildElement("memconfig");
|
|
|
|
config.BankwiseLogic = queryBoolParameter(configuration, "bankwiseLogic");
|
|
config.OpenPagePolicy = queryBoolParameter(configuration, "openPagePolicy");
|
|
config.AdaptiveOpenPagePolicy = queryBoolParameter(configuration, "adaptiveOpenPagePolicy");
|
|
config.RefreshAwareScheduling = queryBoolParameter(configuration, "refreshAwareScheduling");
|
|
config.MaxNrOfTransactions = queryUIntParameter(configuration, "maxNrOfTransactionsInDram");
|
|
config.Scheduler = queryStringParameter(configuration, "scheduler");
|
|
config.Capsize = queryUIntParameter(configuration, "capsize");
|
|
|
|
string mode = queryStringParameter(configuration, "powerDownMode");
|
|
if (mode.compare("Staggered") == 0)
|
|
{
|
|
config.powerDownMode = PowerDownMode::Staggered;
|
|
}
|
|
else if (mode.compare("TimeoutPDN") == 0)
|
|
{
|
|
config.powerDownMode = PowerDownMode::TimeoutPDN;
|
|
}
|
|
else if (mode.compare("TimeoutSREF") == 0)
|
|
{
|
|
config.powerDownMode = PowerDownMode::TimeoutSREF;
|
|
}
|
|
config.powerDownTimeout = queryUIntParameter(configuration, "powerDownTimeout") * config.Timings.clk;
|
|
|
|
config.databaseRecordingEnabled = queryBoolParameter(configuration, "databaseRecordingEnabled");
|
|
}
|
|
|
|
void MemSpecLoader::loadMemSpec(Configuration& config, XMLElement* memspec)
|
|
{
|
|
config.MemoryId = queryStringParameter(memspec, "memoryId");
|
|
config.MemoryType = queryStringParameter(memspec, "memoryType");
|
|
|
|
if (config.MemoryType == "DDR4")
|
|
{
|
|
loadDDR4(config, memspec);
|
|
}
|
|
else if (config.MemoryType == "WIDEIO_SDR")
|
|
{
|
|
loadWideIO(config, memspec);
|
|
}
|
|
else
|
|
{
|
|
reportFatal("ConfigurationLoader", "Unsupported DRAM type");
|
|
}
|
|
}
|
|
|
|
void MemSpecLoader::loadDDR4(Configuration& config, XMLElement* memspec)
|
|
{
|
|
//MemSpecification
|
|
XMLElement* architecture = memspec->FirstChildElement("memarchitecturespec");
|
|
|
|
config.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks");
|
|
config.NumberOfBankGroups = queryUIntParameter(architecture, "nbrOfBankGroups");
|
|
config.BurstLength = queryUIntParameter(architecture, "burstLength");
|
|
config.nActivate = 4;
|
|
config.DataRate = queryUIntParameter(architecture, "dataRate");
|
|
config.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
|
|
|
//MemTimings
|
|
XMLElement* timings = memspec->FirstChildElement("memtimingspec");
|
|
double clkMhz = queryDoubleParameter(timings, "clkMhz");
|
|
sc_time clk = sc_time(1 / clkMhz, SC_US);
|
|
config.Timings.clk = clk;
|
|
|
|
config.Timings.tRP = clk * queryUIntParameter(timings, "RP");
|
|
config.Timings.tRAS = clk * queryUIntParameter(timings, "RAS");
|
|
config.Timings.tRC = clk * queryUIntParameter(timings, "RC");
|
|
config.Timings.tRTP = clk * queryUIntParameter(timings, "RTP");
|
|
config.Timings.tRRD_S = clk * queryUIntParameter(timings, "RRD_S");
|
|
config.Timings.tRRD_L = clk * queryUIntParameter(timings, "RRD_L");
|
|
config.Timings.tCCD_S = clk * queryUIntParameter(timings, "CCD_S");
|
|
config.Timings.tCCD_L = clk * queryUIntParameter(timings, "CCD_L");
|
|
config.Timings.tRCD = clk * queryUIntParameter(timings, "RCD");
|
|
config.Timings.tNAW = clk * queryUIntParameter(timings, "FAW");
|
|
config.Timings.tRL = clk * queryUIntParameter(timings, "RL");
|
|
config.Timings.tWL = clk * queryUIntParameter(timings, "WL");
|
|
config.Timings.tWR = clk * queryUIntParameter(timings, "WR");
|
|
config.Timings.tWTR_S = clk * queryUIntParameter(timings, "WTR_S");
|
|
config.Timings.tWTR_L = clk * queryUIntParameter(timings, "WTR_L");
|
|
config.Timings.tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
|
config.Timings.tCKE = clk * queryUIntParameter(timings, "CKE");
|
|
config.Timings.tXP = clk * queryUIntParameter(timings, "XP");
|
|
config.Timings.tXPDLL = clk * queryUIntParameter(timings, "XPDLL");
|
|
config.Timings.tXSR = clk * queryUIntParameter(timings, "XS");
|
|
config.Timings.tXSRDLL = clk * queryUIntParameter(timings, "XSDLL");
|
|
config.Timings.tAL = clk * queryUIntParameter(timings, "AL");
|
|
config.Timings.tRFC = clk * queryUIntParameter(timings, "RFC");
|
|
config.Timings.tREFI = clk * queryUIntParameter(timings, "REFI");
|
|
|
|
config.Timings.refreshTimings.clear();
|
|
for (unsigned int i = 0; i < config.NumberOfBanks; ++i)
|
|
{
|
|
config.Timings.refreshTimings[Bank(i)] = RefreshTiming(config.Timings.tRFC, config.Timings.tREFI);
|
|
}
|
|
}
|
|
|
|
void MemSpecLoader::loadWideIO(Configuration& config, XMLElement* memspec)
|
|
{
|
|
//MemSpecification
|
|
XMLElement* architecture = memspec->FirstChildElement("memarchitecturespec");
|
|
|
|
config.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks");
|
|
config.NumberOfBankGroups = 1;
|
|
config.BurstLength = queryUIntParameter(architecture, "burstLength");
|
|
config.nActivate = 2;
|
|
config.DataRate = queryUIntParameter(architecture, "dataRate");
|
|
config.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows");
|
|
|
|
//MemTimings
|
|
XMLElement* timings = memspec->FirstChildElement("memtimingspec");
|
|
double clkMhz = queryDoubleParameter(timings, "clkMhz");
|
|
sc_time clk = sc_time(1 / clkMhz, SC_US);
|
|
config.Timings.clk = clk;
|
|
|
|
config.Timings.tRP = clk * queryUIntParameter(timings, "RP");
|
|
config.Timings.tRAS = clk * queryUIntParameter(timings, "RAS");
|
|
config.Timings.tRC = clk * queryUIntParameter(timings, "RC");
|
|
config.Timings.tRRD_S = clk * queryUIntParameter(timings, "RRD");
|
|
config.Timings.tRRD_L = config.Timings.tRRD_S;
|
|
config.Timings.tCCD_S = clk * queryUIntParameter(timings, "CCD");
|
|
config.Timings.tCCD_L = config.Timings.tCCD_S;
|
|
config.Timings.tRCD = clk * queryUIntParameter(timings, "RCD");
|
|
config.Timings.tNAW = clk * queryUIntParameter(timings, "TAW");
|
|
config.Timings.tRL = clk * queryUIntParameter(timings, "RL");
|
|
config.Timings.tWL = clk * queryUIntParameter(timings, "WL");
|
|
config.Timings.tWR = clk * queryUIntParameter(timings, "WR");
|
|
config.Timings.tWTR_S = clk * queryUIntParameter(timings, "WTR");
|
|
config.Timings.tWTR_L = config.Timings.tWTR_S;
|
|
config.Timings.tRTP = clk * queryUIntParameter(timings, "RTP");
|
|
config.Timings.tCKESR = clk * queryUIntParameter(timings, "CKESR");
|
|
config.Timings.tCKE = clk * queryUIntParameter(timings, "CKE");
|
|
config.Timings.tXP = clk * queryUIntParameter(timings, "XP");
|
|
config.Timings.tXPDLL = config.Timings.tXP;
|
|
config.Timings.tXSR = clk * queryUIntParameter(timings, "XS");
|
|
config.Timings.tXSRDLL = config.Timings.tXSR;
|
|
config.Timings.tAL = clk * queryUIntParameter(timings, "AL");
|
|
config.Timings.tRFC = clk * queryUIntParameter(timings, "RFC");
|
|
config.Timings.tREFI = clk * queryUIntParameter(timings, "REFI");
|
|
|
|
config.Timings.refreshTimings.clear();
|
|
for (unsigned int i = 0; i < config.NumberOfBanks; ++i)
|
|
{
|
|
config.Timings.refreshTimings[Bank(i)] = RefreshTiming(config.Timings.tRFC, config.Timings.tREFI);
|
|
}
|
|
|
|
}
|
|
|
|
} /* namespace core */
|