/* * MemSpecLoader.cpp * * Created on: Apr 7, 2014 * Author: jonny */ #include "MemSpecLoader.h" #include "MemSpec.h" #include "../TimingCalculation.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.memSpec.clk; config.databaseRecordingEnabled = queryBoolParameter(configuration, "databaseRecordingEnabled"); } void MemSpecLoader::loadMemSpec(Configuration& config, XMLElement* memspec) { config.memSpec.MemoryId = queryStringParameter(memspec, "memoryId"); config.memSpec.MemoryType = queryStringParameter(memspec, "memoryType"); if (config.memSpec.MemoryType == "DDR4") { loadDDR4(config, memspec); } else if (config.memSpec.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.memSpec.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks"); config.memSpec.NumberOfBankGroups = queryUIntParameter(architecture, "nbrOfBankGroups"); config.memSpec.BurstLength = queryUIntParameter(architecture, "burstLength"); config.memSpec.nActivate = 4; config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate"); config.memSpec.NumberOfRows = queryUIntParameter(architecture, "nbrOfRows"); //MemTimings XMLElement* timings = memspec->FirstChildElement("memtimingspec"); double clkMhz = queryDoubleParameter(timings, "clkMhz"); config.memSpec.clk = FrequencyToClk(clkMhz); sc_time clk = config.memSpec.clk; config.memSpec.tRP = clk * queryUIntParameter(timings, "RP"); config.memSpec.tRAS = clk * queryUIntParameter(timings, "RAS"); config.memSpec.tRC = clk * queryUIntParameter(timings, "RC"); config.memSpec.tRTP = clk * queryUIntParameter(timings, "RTP"); config.memSpec.tRRD_S = clk * queryUIntParameter(timings, "RRD_S"); config.memSpec.tRRD_L = clk * queryUIntParameter(timings, "RRD_L"); config.memSpec.tCCD_S = clk * queryUIntParameter(timings, "CCD_S"); config.memSpec.tCCD_L = clk * queryUIntParameter(timings, "CCD_L"); config.memSpec.tRCD = clk * queryUIntParameter(timings, "RCD"); config.memSpec.tNAW = clk * queryUIntParameter(timings, "FAW"); config.memSpec.tRL = clk * queryUIntParameter(timings, "RL"); config.memSpec.tWL = clk * queryUIntParameter(timings, "WL"); config.memSpec.tWR = clk * queryUIntParameter(timings, "WR"); config.memSpec.tWTR_S = clk * queryUIntParameter(timings, "WTR_S"); config.memSpec.tWTR_L = clk * queryUIntParameter(timings, "WTR_L"); config.memSpec.tCKESR = clk * queryUIntParameter(timings, "CKESR"); config.memSpec.tCKE = clk * queryUIntParameter(timings, "CKE"); config.memSpec.tXP = clk * queryUIntParameter(timings, "XP"); config.memSpec.tXPDLL = clk * queryUIntParameter(timings, "XPDLL"); config.memSpec.tXSR = clk * queryUIntParameter(timings, "XS"); config.memSpec.tXSRDLL = clk * queryUIntParameter(timings, "XSDLL"); config.memSpec.tAL = clk * queryUIntParameter(timings, "AL"); config.memSpec.tRFC = clk * queryUIntParameter(timings, "RFC"); config.memSpec.tREFI = clk * queryUIntParameter(timings, "REFI"); config.memSpec.refreshTimings.clear(); for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; ++i) { config.memSpec.refreshTimings[Bank(i)] = RefreshTiming(config.memSpec.tRFC, config.memSpec.tREFI); } } void MemSpecLoader::loadWideIO(Configuration& config, XMLElement* memspec) { //MemSpecification XMLElement* architecture = memspec->FirstChildElement("memarchitecturespec"); config.memSpec.NumberOfBanks = queryUIntParameter(architecture, "nbrOfBanks"); config.memSpec.NumberOfBankGroups = 1; config.memSpec.BurstLength = queryUIntParameter(architecture, "burstLength"); config.memSpec.nActivate = 2; config.memSpec.DataRate = queryUIntParameter(architecture, "dataRate"); config.memSpec.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.memSpec.clk = clk; config.memSpec.tRP = clk * queryUIntParameter(timings, "RP"); config.memSpec.tRAS = clk * queryUIntParameter(timings, "RAS"); config.memSpec.tRC = clk * queryUIntParameter(timings, "RC"); config.memSpec.tRRD_S = clk * queryUIntParameter(timings, "RRD"); config.memSpec.tRRD_L = config.memSpec.tRRD_S; config.memSpec.tCCD_S = clk * queryUIntParameter(timings, "CCD"); config.memSpec.tCCD_L = config.memSpec.tCCD_S; config.memSpec.tRCD = clk * queryUIntParameter(timings, "RCD"); config.memSpec.tNAW = clk * queryUIntParameter(timings, "TAW"); config.memSpec.tRL = clk * queryUIntParameter(timings, "RL"); config.memSpec.tWL = clk * queryUIntParameter(timings, "WL"); config.memSpec.tWR = clk * queryUIntParameter(timings, "WR"); config.memSpec.tWTR_S = clk * queryUIntParameter(timings, "WTR"); config.memSpec.tWTR_L = config.memSpec.tWTR_S; config.memSpec.tRTP = clk * queryUIntParameter(timings, "RTP"); config.memSpec.tCKESR = clk * queryUIntParameter(timings, "CKESR"); config.memSpec.tCKE = clk * queryUIntParameter(timings, "CKE"); config.memSpec.tXP = clk * queryUIntParameter(timings, "XP"); config.memSpec.tXPDLL = config.memSpec.tXP; config.memSpec.tXSR = clk * queryUIntParameter(timings, "XS"); config.memSpec.tXSRDLL = config.memSpec.tXSR; config.memSpec.tAL = clk * queryUIntParameter(timings, "AL"); config.memSpec.tRFC = clk * queryUIntParameter(timings, "RFC"); config.memSpec.tREFI = clk * queryUIntParameter(timings, "REFI"); config.memSpec.refreshTimings.clear(); for (unsigned int i = 0; i < config.memSpec.NumberOfBanks; ++i) { config.memSpec.refreshTimings[Bank(i)] = RefreshTiming(config.memSpec.tRFC, config.memSpec.tREFI); } } } /* namespace core */