From 3d0e321075c4456f42d5382dd2acbb8ff0a683dd Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Fri, 5 Nov 2021 09:35:25 +0100 Subject: [PATCH] Introduce a gui simulation dialog in TraceAnalyzer A simulation dialog is added to the TraceAnalyzer that can be used to directly load a json config, edit it and start a simulation based on the changes that were made, even without saving again. The simulation results are opened directly after suceeding. --- .../common/configuration/AddressMapping.cpp | 13 + .../src/common/configuration/AddressMapping.h | 3 + .../common/configuration/Configuration.cpp | 13 + .../src/common/configuration/Configuration.h | 3 + .../src/common/configuration/McConfig.cpp | 36 +- .../src/common/configuration/McConfig.h | 17 +- .../src/common/configuration/SimConfig.cpp | 13 + .../src/common/configuration/SimConfig.h | 3 + .../common/configuration/ThermalConfig.cpp | 13 + .../src/common/configuration/ThermalConfig.h | 3 + .../src/common/configuration/TraceSetup.cpp | 13 + .../src/common/configuration/TraceSetup.h | 3 + .../common/configuration/memspec/MemSpec.cpp | 10 +- .../common/configuration/memspec/MemSpec.h | 3 +- .../library/src/common/configuration/util.h | 10 + .../src/configuration/Configuration.cpp | 247 ++---------- DRAMSys/library/src/simulation/DRAMSys.cpp | 3 +- DRAMSys/traceAnalyzer/CMakeLists.txt | 3 + DRAMSys/traceAnalyzer/simulationdialog.cpp | 377 ++++++++++++++++++ DRAMSys/traceAnalyzer/simulationdialog.h | 100 +++++ DRAMSys/traceAnalyzer/simulationdialog.ui | 345 ++++++++++++++++ DRAMSys/traceAnalyzer/traceanalyzer.cpp | 12 + DRAMSys/traceAnalyzer/traceanalyzer.h | 1 + DRAMSys/traceAnalyzer/traceanalyzer.ui | 15 + 24 files changed, 1041 insertions(+), 218 deletions(-) create mode 100644 DRAMSys/traceAnalyzer/simulationdialog.cpp create mode 100644 DRAMSys/traceAnalyzer/simulationdialog.h create mode 100644 DRAMSys/traceAnalyzer/simulationdialog.ui diff --git a/DRAMSys/library/src/common/configuration/AddressMapping.cpp b/DRAMSys/library/src/common/configuration/AddressMapping.cpp index 8ab105c0..c3a57881 100644 --- a/DRAMSys/library/src/common/configuration/AddressMapping.cpp +++ b/DRAMSys/library/src/common/configuration/AddressMapping.cpp @@ -101,4 +101,17 @@ void from_json(const json &j, XorPair &x) j.at("SECOND").get_to(x.second); } +void from_dump(const std::string &dump, AddressMapping &c) +{ + json json_addressmapping = json::parse(dump).at("addressmapping"); + json_addressmapping.get_to(c); +} + +std::string dump(const AddressMapping &c, unsigned int indentation) +{ + json json_addressmapping; + json_addressmapping["addressmapping"] = c; + return json_addressmapping.dump(indentation); +} + } // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/AddressMapping.h b/DRAMSys/library/src/common/configuration/AddressMapping.h index a0ab60ff..28a6c097 100644 --- a/DRAMSys/library/src/common/configuration/AddressMapping.h +++ b/DRAMSys/library/src/common/configuration/AddressMapping.h @@ -71,6 +71,9 @@ struct AddressMapping void to_json(json &j, const AddressMapping &m); void from_json(const json &j, AddressMapping &m); +void from_dump(const std::string &dump, AddressMapping &c); +std::string dump(const AddressMapping &c, unsigned int indentation = -1); + } // namespace Configuration #endif // ADDRESSMAPPING_H diff --git a/DRAMSys/library/src/common/configuration/Configuration.cpp b/DRAMSys/library/src/common/configuration/Configuration.cpp index f2dd99eb..ed331aaf 100644 --- a/DRAMSys/library/src/common/configuration/Configuration.cpp +++ b/DRAMSys/library/src/common/configuration/Configuration.cpp @@ -67,6 +67,19 @@ void from_json(const json &j, Configuration &c) j.at("tracesetup").get_to(c.traceSetup); } +void from_dump(const std::string &dump, Configuration &c) +{ + json json_simulation = json::parse(dump).at("simulation"); + json_simulation.get_to(c); +} + +std::string dump(const Configuration &c, unsigned int indentation) +{ + json json_simulation; + json_simulation["simulation"] = c; + return json_simulation.dump(indentation); +} + Configuration from_path(const std::string &path, const std::string &resourceDirectory) { Configuration::resourceDirectory = resourceDirectory; diff --git a/DRAMSys/library/src/common/configuration/Configuration.h b/DRAMSys/library/src/common/configuration/Configuration.h index c5588c2a..7bbca42d 100644 --- a/DRAMSys/library/src/common/configuration/Configuration.h +++ b/DRAMSys/library/src/common/configuration/Configuration.h @@ -78,6 +78,9 @@ struct Configuration void to_json(json &j, const Configuration &p); void from_json(const json &j, Configuration &p); +void from_dump(const std::string &dump, Configuration &c); +std::string dump(const Configuration &c, unsigned int indentation = -1); + Configuration from_path(const std::string &path, const std::string &resourceDirectory = DRAMSysResourceDirectory); } // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/McConfig.cpp b/DRAMSys/library/src/common/configuration/McConfig.cpp index 4a28278c..945388d0 100644 --- a/DRAMSys/library/src/common/configuration/McConfig.cpp +++ b/DRAMSys/library/src/common/configuration/McConfig.cpp @@ -52,7 +52,13 @@ void to_json(json &j, const McConfig &c) {"PowerDownPolicy", c.powerDownPolicy}, {"Arbiter", c.arbiter}, {"MaxActiveTransactions", c.maxActiveTransactions}, - {"RefreshManagment", c.refreshManagement}}; + {"RefreshManagment", c.refreshManagement}, + {"ArbitrationDelayFw", c.arbitrationDelayFw}, + {"ArbitrationDelayBw", c.arbitrationDelayBw}, + {"ThinkDelayFw", c.thinkDelayFw}, + {"ThinkDelayBw", c.thinkDelayBw}, + {"PhyDelayFw", c.phyDelayFw}, + {"PhyDelayBw", c.phyDelayBw}}; remove_null_values(j); } @@ -100,6 +106,24 @@ void from_json(const json &j, McConfig &c) if (j_mcconfig.contains("RefreshManagment")) j_mcconfig.at("RefreshManagment").get_to(c.refreshManagement); + if (j_mcconfig.contains("ArbitrationDelayFw")) + j_mcconfig.at("ArbitrationDelayFw").get_to(c.arbitrationDelayFw); + + if (j_mcconfig.contains("ArbitrationDelayBw")) + j_mcconfig.at("ArbitrationDelayBw").get_to(c.arbitrationDelayBw); + + if (j_mcconfig.contains("ThinkDelayFw")) + j_mcconfig.at("ThinkDelayFw").get_to(c.thinkDelayFw); + + if (j_mcconfig.contains("ThinkDelayBw")) + j_mcconfig.at("ThinkDelayBw").get_to(c.thinkDelayBw); + + if (j_mcconfig.contains("PhyDelayFw")) + j_mcconfig.at("PhyDelayFw").get_to(c.phyDelayFw); + + if (j_mcconfig.contains("PhyDelayBw")) + j_mcconfig.at("PhyDelayBw").get_to(c.phyDelayBw); + invalidateEnum(c.pagePolicy); invalidateEnum(c.scheduler); invalidateEnum(c.schedulerBuffer); @@ -111,11 +135,17 @@ void from_json(const json &j, McConfig &c) invalidateEnum(c.arbiter); } -std::string dump(const McConfig &c) +void from_dump(const std::string &dump, McConfig &c) +{ + json json_mcconfig = json::parse(dump).at("mcconfig"); + json_mcconfig.get_to(c); +} + +std::string dump(const McConfig &c, unsigned int indentation) { json json_mcconfig; json_mcconfig["mcconfig"] = c; - return json_mcconfig.dump(); + return json_mcconfig.dump(indentation); } } // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/McConfig.h b/DRAMSys/library/src/common/configuration/McConfig.h index 701b5d09..abc7bcd0 100644 --- a/DRAMSys/library/src/common/configuration/McConfig.h +++ b/DRAMSys/library/src/common/configuration/McConfig.h @@ -119,14 +119,20 @@ enum class RefreshPolicy PerBank, Per2Bank, SameBank, + Rankwise, + Bankwise, + Groupwise, Invalid = -1 }; NLOHMANN_JSON_SERIALIZE_ENUM(RefreshPolicy, {{RefreshPolicy::Invalid, nullptr}, + {RefreshPolicy::NoRefresh, "NoRefresh"}, {RefreshPolicy::AllBank, "AllBank"}, {RefreshPolicy::PerBank, "PerBank"}, {RefreshPolicy::Per2Bank, "Per2Bank"}, - {RefreshPolicy::SameBank, "SameBank"}}) + {RefreshPolicy::Rankwise, "Rankwise"}, + {RefreshPolicy::Bankwise, "Bankwise"}, + {RefreshPolicy::Groupwise, "Groupwise"}}) enum class PowerDownPolicy { @@ -167,12 +173,19 @@ struct McConfig Optional arbiter; Optional maxActiveTransactions; Optional refreshManagement; + Optional arbitrationDelayFw; + Optional arbitrationDelayBw; + Optional thinkDelayFw; + Optional thinkDelayBw; + Optional phyDelayFw; + Optional phyDelayBw; }; void to_json(json &j, const McConfig &c); void from_json(const json &j, McConfig &c); -std::string dump(const McConfig &c); +void from_dump(const std::string &dump, McConfig &c); +std::string dump(const McConfig &c, unsigned int indentation = -1); } // namespace Configuration diff --git a/DRAMSys/library/src/common/configuration/SimConfig.cpp b/DRAMSys/library/src/common/configuration/SimConfig.cpp index 34cc41ef..3459e64c 100644 --- a/DRAMSys/library/src/common/configuration/SimConfig.cpp +++ b/DRAMSys/library/src/common/configuration/SimConfig.cpp @@ -110,4 +110,17 @@ void from_json(const json &j, SimConfig &c) invalidateEnum(c.storeMode); } +void from_dump(const std::string &dump, SimConfig &c) +{ + json json_simconfig = json::parse(dump).at("simconfig"); + json_simconfig.get_to(c); +} + +std::string dump(const SimConfig &c, unsigned int indentation) +{ + json json_simconfig; + json_simconfig["simconfig"] = c; + return json_simconfig.dump(indentation); +} + } // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/SimConfig.h b/DRAMSys/library/src/common/configuration/SimConfig.h index d0ca2fa5..f9bbbedd 100644 --- a/DRAMSys/library/src/common/configuration/SimConfig.h +++ b/DRAMSys/library/src/common/configuration/SimConfig.h @@ -92,6 +92,9 @@ struct SimConfig void to_json(json &j, const SimConfig &c); void from_json(const json &j, SimConfig &c); +void from_dump(const std::string &dump, SimConfig &c); +std::string dump(const SimConfig &c, unsigned int indentation = -1); + } // namespace Configuration #endif diff --git a/DRAMSys/library/src/common/configuration/ThermalConfig.cpp b/DRAMSys/library/src/common/configuration/ThermalConfig.cpp index b6305269..fdcbd0e2 100644 --- a/DRAMSys/library/src/common/configuration/ThermalConfig.cpp +++ b/DRAMSys/library/src/common/configuration/ThermalConfig.cpp @@ -105,4 +105,17 @@ void from_json(const json &j, PowerInfo &c) } } +void from_dump(const std::string &dump, ThermalConfig &c) +{ + json json_thermalconfig = json::parse(dump).at("thermalconfig"); + json_thermalconfig.get_to(c); +} + +std::string dump(const ThermalConfig &c, unsigned int indentation) +{ + json json_thermalconfig; + json_thermalconfig["thermalconfig"] = c; + return json_thermalconfig.dump(indentation); +} + } // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/ThermalConfig.h b/DRAMSys/library/src/common/configuration/ThermalConfig.h index 1bb063ce..44497346 100644 --- a/DRAMSys/library/src/common/configuration/ThermalConfig.h +++ b/DRAMSys/library/src/common/configuration/ThermalConfig.h @@ -112,6 +112,9 @@ struct ThermalConfig void to_json(json &j, const ThermalConfig &c); void from_json(const json &j, ThermalConfig &c); +void from_dump(const std::string &dump, ThermalConfig &c); +std::string dump(const ThermalConfig &c, unsigned int indentation = -1); + } // namespace Configuration #endif // THERMALCONFIG_H diff --git a/DRAMSys/library/src/common/configuration/TraceSetup.cpp b/DRAMSys/library/src/common/configuration/TraceSetup.cpp index ce9a98fc..f2dd330e 100644 --- a/DRAMSys/library/src/common/configuration/TraceSetup.cpp +++ b/DRAMSys/library/src/common/configuration/TraceSetup.cpp @@ -136,4 +136,17 @@ void from_json(const json &j, TraceSetup &c) } } +void from_dump(const std::string &dump, TraceSetup &c) +{ + json json_tracesetup = json::parse(dump).at("tracesetup"); + json_tracesetup.get_to(c); +} + +std::string dump(const TraceSetup &c, unsigned int indentation) +{ + json json_tracesetup; + json_tracesetup["tracesetup"] = c; + return json_tracesetup.dump(indentation); +} + } // namespace DRAMSysConfiguration diff --git a/DRAMSys/library/src/common/configuration/TraceSetup.h b/DRAMSys/library/src/common/configuration/TraceSetup.h index f8062b2e..2a84bd61 100644 --- a/DRAMSys/library/src/common/configuration/TraceSetup.h +++ b/DRAMSys/library/src/common/configuration/TraceSetup.h @@ -109,6 +109,9 @@ struct TraceSetup void to_json(json &j, const TraceSetup &c); void from_json(const json &j, TraceSetup &c); +void from_dump(const std::string &dump, TraceSetup &c); +std::string dump(const TraceSetup &c, unsigned int indentation = -1); + } // namespace Configuration #endif diff --git a/DRAMSys/library/src/common/configuration/memspec/MemSpec.cpp b/DRAMSys/library/src/common/configuration/memspec/MemSpec.cpp index 7453b42a..cc5dee89 100644 --- a/DRAMSys/library/src/common/configuration/memspec/MemSpec.cpp +++ b/DRAMSys/library/src/common/configuration/memspec/MemSpec.cpp @@ -62,11 +62,17 @@ void from_json(const json &j, MemSpec &c) j_memspecs.at("mempowerspec").get_to(c.memPowerSpec); } -std::string dump(const MemSpec &c) +void from_dump(const std::string &dump, MemSpec &c) +{ + json json_memspec = json::parse(dump).at("memspec"); + json_memspec.get_to(c); +} + +std::string dump(const MemSpec &c, unsigned int indentation) { json json_memspec; json_memspec["memspec"] = c; - return json_memspec.dump(); + return json_memspec.dump(indentation); } } // namespace Configuration diff --git a/DRAMSys/library/src/common/configuration/memspec/MemSpec.h b/DRAMSys/library/src/common/configuration/memspec/MemSpec.h index 0fde0fa8..66c0a317 100644 --- a/DRAMSys/library/src/common/configuration/memspec/MemSpec.h +++ b/DRAMSys/library/src/common/configuration/memspec/MemSpec.h @@ -61,7 +61,8 @@ struct MemSpec void to_json(json &j, const MemSpec &c); void from_json(const json &j, MemSpec &c); -std::string dump(const MemSpec &c); +void from_dump(const std::string &dump, MemSpec &c); +std::string dump(const MemSpec &c, unsigned int indentation = -1); } // namespace Configuration diff --git a/DRAMSys/library/src/common/configuration/util.h b/DRAMSys/library/src/common/configuration/util.h index c6090fa3..5d61f9a7 100644 --- a/DRAMSys/library/src/common/configuration/util.h +++ b/DRAMSys/library/src/common/configuration/util.h @@ -75,6 +75,16 @@ public: { this->second = false; } + + /** + * This methods only purpose is to make a optional type + * valid so that it can be written to by reference. + */ + T &setByReference() + { + this->second = true; + return this->first; + } }; template diff --git a/DRAMSys/library/src/configuration/Configuration.cpp b/DRAMSys/library/src/configuration/Configuration.cpp index ac9614d3..4a003206 100644 --- a/DRAMSys/library/src/configuration/Configuration.cpp +++ b/DRAMSys/library/src/configuration/Configuration.cpp @@ -77,212 +77,6 @@ enum sc_time_unit string2TimeUnit(const std::string &s) } } -// void Configuration::setParameter(const std::string &name, const nlohmann::json &value) -// { -// MCConfig -// if (name == "PagePolicy") -// { -// if (value == "Open") -// pagePolicy = PagePolicy::Open; -// else if (value == "Closed") -// pagePolicy = PagePolicy::Closed; -// else if (value == "OpenAdaptive") -// pagePolicy = PagePolicy::OpenAdaptive; -// else if (value == "ClosedAdaptive") -// pagePolicy = PagePolicy::ClosedAdaptive; -// else -// SC_REPORT_FATAL("Configuration", "Unsupported page policy!"); -// } -// else if (name == "Scheduler") -// { -// if (value == "Fifo") -// scheduler = Scheduler::Fifo; -// else if (value == "FrFcfs") -// scheduler = Scheduler::FrFcfs; -// else if (value == "FrFcfsGrp") -// scheduler = Scheduler::FrFcfsGrp; -// else -// SC_REPORT_FATAL("Configuration", "Unsupported scheduler!"); -// } -// else if (name == "SchedulerBuffer") -// { -// if (value == "Bankwise") -// schedulerBuffer = SchedulerBuffer::Bankwise; -// else if (value == "ReadWrite") -// schedulerBuffer = SchedulerBuffer::ReadWrite; -// else if (value == "Shared") -// schedulerBuffer = SchedulerBuffer::Shared; -// else -// SC_REPORT_FATAL("Configuration", "Unsupported scheduler buffer!"); -// } -// else if (name == "RequestBufferSize") -// { -// requestBufferSize = value; -// if (requestBufferSize == 0) -// SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!"); -// } -// else if (name == "CmdMux") -// { -// if (value == "Oldest") -// cmdMux = CmdMux::Oldest; -// else if (value == "Strict") -// cmdMux = CmdMux::Strict; -// else -// SC_REPORT_FATAL("Configuration", "Unsupported cmd mux!"); -// } -// else if (name == "RespQueue") -// { -// if (value == "Fifo") -// respQueue = RespQueue::Fifo; -// else if (value == "Reorder") -// respQueue = RespQueue::Reorder; -// else -// SC_REPORT_FATAL("Configuration", "Unsupported response queue!"); -// } -// else if (name == "Arbiter") -// { -// if (value == "Simple") -// arbiter = Arbiter::Simple; -// else if (value == "Fifo") -// arbiter = Arbiter::Fifo; -// else if (value == "Reorder") -// arbiter = Arbiter::Reorder; -// else -// SC_REPORT_FATAL("Configuration", "Unsupported arbiter!"); -// } -// else if (name == "RefreshPolicy") -// { -// if (value == "NoRefresh") -// refreshPolicy = RefreshPolicy::NoRefresh; -// else if (value == "AllBank" || value == "Rankwise") -// refreshPolicy = RefreshPolicy::AllBank; -// else if (value == "PerBank" || value == "Bankwise") -// refreshPolicy = RefreshPolicy::PerBank; -// else if (value == "SameBank" || value == "Groupwise") -// refreshPolicy = RefreshPolicy::SameBank; -// else -// SC_REPORT_FATAL("Configuration", "Unsupported refresh policy!"); -// } -// else if (name == "RefreshMaxPostponed") -// refreshMaxPostponed = value; -// else if (name == "RefreshMaxPulledin") -// refreshMaxPulledin = value; -// else if (name == "PowerDownPolicy") -// { -// if (value == "NoPowerDown") -// powerDownPolicy = PowerDownPolicy::NoPowerDown; -// else if (value == "Staggered") -// powerDownPolicy = PowerDownPolicy::Staggered; -// else -// SC_REPORT_FATAL("Configuration", "Unsupported power down policy!"); -// } -// else if (name == "RefreshManagement") -// refreshManagement = value; -// else if (name == "PowerDownTimeout") -// powerDownTimeout = value; -// else if (name == "MaxActiveTransactions") -// maxActiveTransactions = value; -// else if (name == "ArbitrationDelayFw") -// arbitrationDelayFw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; -// else if (name == "ArbitrationDelayBw") -// arbitrationDelayBw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; -// else if (name == "ThinkDelayFw") -// thinkDelayFw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; -// else if (name == "ThinkDelayBw") -// thinkDelayBw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; -// else if (name == "PhyDelayFw") -// phyDelayFw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; -// else if (name == "PhyDelayBw") -// phyDelayBw = std::round(sc_time(value, SC_NS) / memSpec->tCK) * memSpec->tCK; -// SimConfig------------------------------------------------ -// else if (name == "SimulationName") -// simulationName = value; -// else if (name == "DatabaseRecording") -// databaseRecording = value; -// else if (name == "PowerAnalysis") -// powerAnalysis = value; -// else if (name == "EnableWindowing") -// enableWindowing = value; -// else if (name == "WindowSize") -// { -// windowSize = value; -// if (windowSize == 0) -// SC_REPORT_FATAL("Configuration", "Minimum window size is 1"); -// } -// else if (name == "Debug") -// debug = value; -// else if (name == "ThermalSimulation") -// thermalSimulation = value; -// else if (name == "SimulationProgressBar") -// simulationProgressBar = value; -// else if (name == "AddressOffset") -// addressOffset = value; -// else if (name == "UseMalloc") -// useMalloc = value; -// else if (name == "CheckTLM2Protocol") -// checkTLM2Protocol = value; -// else if (name == "ECCControllerMode") -// { -// if (value == "Disabled") -// eccMode = ECCMode::Disabled; -// else if (value == "Hamming") -// eccMode = ECCMode::Hamming; -// else -// SC_REPORT_FATAL("Configuration", "Unsupported ECC mode!"); -// } -// Specification for ErrorChipSeed, ErrorCSVFile path and StoreMode -// else if (name == "ErrorChipSeed") -// errorChipSeed = value; -// else if (name == "ErrorCSVFile") -// errorCSVFile = value; -// else if (name == "StoreMode") -// { -// if (value == "NoStorage") -// storeMode = StoreMode::NoStorage; -// else if (value == "Store") -// storeMode = StoreMode::Store; -// else if (value == "ErrorModel") -// storeMode = StoreMode::ErrorModel; -// else -// SC_REPORT_FATAL("Configuration", "Unsupported store mode!"); -// } -// -// Temperature Simulation related -// else if (name == "TemperatureScale") -// { -// if (value != "Celsius" && value != "Fahrenheit" && value != "Kelvin") -// SC_REPORT_FATAL("Configuration", -// ("Invalid value for parameter " + name + ".").c_str()); -// temperatureSim.temperatureScale = value; -// } -// else if (name == "StaticTemperatureDefaultValue") -// temperatureSim.staticTemperatureDefaultValue = value; -// else if (name == "ThermalSimPeriod") -// temperatureSim.thermalSimPeriod = value; -// else if (name == "ThermalSimUnit") -// temperatureSim.thermalSimUnit = string2TimeUnit(value); -// else if (name == "PowerInfoFile") -// { -// temperatureSim.powerInfoFile = value; -// temperatureSim.parsePowerInfoFile(); -// } -// else if (name == "IceServerIp") -// temperatureSim.iceServerIp = value; -// else if (name == "IceServerPort") -// temperatureSim.iceServerPort = value; -// else if (name == "SimPeriodAdjustFactor") -// temperatureSim.simPeriodAdjustFactor = value; -// else if (name == "NPowStableCyclesToIncreasePeriod") -// temperatureSim.nPowStableCyclesToIncreasePeriod = value; -// else if (name == "GenerateTemperatureMap") -// temperatureSim.generateTemperatureMap = value; -// else if (name == "GeneratePowerMap") -// temperatureSim.generatePowerMap = value; -// else -// SC_REPORT_FATAL("Configuration", -// ("Parameter " + name + " not defined in Configuration").c_str()); -// } - // Changes the number of bytes depeding on the ECC Controller. This function is needed for modules which get data directly or indirectly from the ECC Controller unsigned int Configuration::adjustNumBytesAfterECC(unsigned nBytes) const { @@ -343,6 +137,8 @@ void Configuration::loadSimConfig(Configuration &config, const DRAMSysConfigurat if (simConfig.windowSize.isValid()) config.windowSize = simConfig.windowSize.getValue(); + if (config.windowSize == 0) + SC_REPORT_FATAL("Configuration", "Minimum window size is 1"); if (simConfig.errorCsvFile.isValid()) config.errorCSVFile = simConfig.errorCsvFile.getValue(); @@ -451,6 +247,9 @@ void Configuration::loadMCConfig(Configuration &config, const DRAMSysConfigurati if (mcConfig.requestBufferSize.isValid()) config.requestBufferSize = mcConfig.requestBufferSize.getValue(); + if (config.requestBufferSize == 0) + SC_REPORT_FATAL("Configuration", "Minimum request buffer size is 1!"); + if (mcConfig.cmdMux.isValid()) config.cmdMux = [=] { auto cmdMux = mcConfig.cmdMux.getValue(); @@ -477,13 +276,13 @@ void Configuration::loadMCConfig(Configuration &config, const DRAMSysConfigurati if (policy == DRAMSysConfiguration::RefreshPolicy::NoRefresh) return RefreshPolicy::NoRefresh; - else if (policy == DRAMSysConfiguration::RefreshPolicy::AllBank) + else if (policy == DRAMSysConfiguration::RefreshPolicy::AllBank || policy == DRAMSysConfiguration::RefreshPolicy::Rankwise) return RefreshPolicy::AllBank; - else if (policy == DRAMSysConfiguration::RefreshPolicy::PerBank) + else if (policy == DRAMSysConfiguration::RefreshPolicy::PerBank || policy == DRAMSysConfiguration::RefreshPolicy::Bankwise) return RefreshPolicy::PerBank; else if (policy == DRAMSysConfiguration::RefreshPolicy::Per2Bank) return RefreshPolicy::Per2Bank; - else + else // if (policy == DRAMSysConfiguration::RefreshPolicy::SameBank || policy == DRAMSysConfiguration::RefreshPolicy::Groupwise) return RefreshPolicy::SameBank; }(); @@ -520,6 +319,36 @@ void Configuration::loadMCConfig(Configuration &config, const DRAMSysConfigurati if (mcConfig.refreshManagement.isValid()) config.refreshManagement = mcConfig.refreshManagement.getValue(); + + if (mcConfig.arbitrationDelayFw.isValid()) + { + config.arbitrationDelayFw = std::round(sc_time(mcConfig.arbitrationDelayFw.getValue(), SC_NS) / config.memSpec->tCK) * config.memSpec->tCK; + } + + if (mcConfig.arbitrationDelayBw.isValid()) + { + config.arbitrationDelayBw = std::round(sc_time(mcConfig.arbitrationDelayBw.getValue(), SC_NS) / config.memSpec->tCK) * config.memSpec->tCK; + } + + if (mcConfig.thinkDelayFw.isValid()) + { + config.thinkDelayFw = std::round(sc_time(mcConfig.thinkDelayFw.getValue(), SC_NS) / config.memSpec->tCK) * config.memSpec->tCK; + } + + if (mcConfig.thinkDelayBw.isValid()) + { + config.thinkDelayBw = std::round(sc_time(mcConfig.thinkDelayBw.getValue(), SC_NS) / config.memSpec->tCK) * config.memSpec->tCK; + } + + if (mcConfig.phyDelayFw.isValid()) + { + config.phyDelayFw = std::round(sc_time(mcConfig.phyDelayFw.getValue(), SC_NS) / config.memSpec->tCK) * config.memSpec->tCK; + } + + if (mcConfig.phyDelayBw.isValid()) + { + config.phyDelayBw = std::round(sc_time(mcConfig.phyDelayBw.getValue(), SC_NS) / config.memSpec->tCK) * config.memSpec->tCK; + } } void Configuration::loadMemSpec(Configuration &config, const DRAMSysConfiguration::MemSpec &memSpecConfig) diff --git a/DRAMSys/library/src/simulation/DRAMSys.cpp b/DRAMSys/library/src/simulation/DRAMSys.cpp index 7bf032a8..3578b62b 100644 --- a/DRAMSys/library/src/simulation/DRAMSys.cpp +++ b/DRAMSys/library/src/simulation/DRAMSys.cpp @@ -77,7 +77,8 @@ DRAMSys::DRAMSys(const sc_core::sc_module_name &name, logo(); // Load config and initialize modules - Configuration::getInstance().loadMemSpec(Configuration::getInstance(), config.memSpec); + // Important: The memSpec needs to be the first configuration to be loaded! + Configuration::loadMemSpec(Configuration::getInstance(), config.memSpec); Configuration::loadMCConfig(Configuration::getInstance(), config.mcConfig); Configuration::loadSimConfig(Configuration::getInstance(), config.simConfig); diff --git a/DRAMSys/traceAnalyzer/CMakeLists.txt b/DRAMSys/traceAnalyzer/CMakeLists.txt index 28e71f52..31cf682c 100644 --- a/DRAMSys/traceAnalyzer/CMakeLists.txt +++ b/DRAMSys/traceAnalyzer/CMakeLists.txt @@ -100,6 +100,7 @@ add_executable(TraceAnalyzer presentation/traceselector.cpp businessObjects/configmodels.cpp businessObjects/commentmodel.cpp + simulationdialog.cpp selectmetrics.ui preferences.ui @@ -108,6 +109,7 @@ add_executable(TraceAnalyzer tracefiletab.ui queryeditor.ui traceanalyzer.ui + simulationdialog.ui scripts/memUtil.py scripts/metrics.py @@ -131,4 +133,5 @@ target_link_libraries(TraceAnalyzer PRIVATE ${QWT_LIBRARY} PRIVATE Qt5::Widgets PRIVATE Qt5::Sql + PRIVATE DRAMSysConfiguration ) diff --git a/DRAMSys/traceAnalyzer/simulationdialog.cpp b/DRAMSys/traceAnalyzer/simulationdialog.cpp new file mode 100644 index 00000000..1cea4728 --- /dev/null +++ b/DRAMSys/traceAnalyzer/simulationdialog.cpp @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2021s, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Derek Christ + */ + +#include "simulationdialog.h" + +#include +#include +#include +#include +#include +#include + +SimulationDialog::SimulationDialog(QWidget *parent) : QWidget(parent), ui(new Ui::SimulationDialog) +{ + ui->setupUi(this); + + showStopButton(false); + + // Try to find path to DRAMSys + { + QFileInfo fileInfo; + + fileInfo.setFile("../simulator/DRAMSys"); + if (fileInfo.isFile()) + ui->dramSysPath->setText(fileInfo.absoluteFilePath()); + + fileInfo.setFile("../simulator/DRAMSys.exe"); + if (fileInfo.isFile()) + ui->dramSysPath->setText(fileInfo.absoluteFilePath()); + + fileInfo.setFile("simulator/DRAMSys"); + if (fileInfo.isFile()) + ui->dramSysPath->setText(fileInfo.absoluteFilePath()); + + fileInfo.setFile("simulator/DRAMSys.exe"); + if (fileInfo.isFile()) + ui->dramSysPath->setText(fileInfo.absoluteFilePath()); + } + + ui->outputDirLineEdit->setText(QDir::currentPath()); +} + +void SimulationDialog::on_browseDramSysButton_clicked() +{ + QString fileName = + QFileDialog::getOpenFileName(this, ui->browseDramSysButton->text(), {}, "DRAMSys executable (*)"); + ui->dramSysPath->setText(fileName); +} + +void SimulationDialog::on_browseConfigButton_clicked() +{ + QString fileName = + QFileDialog::getOpenFileName(this, ui->browseConfigButton->text(), {}, "Configuration file (*.json)"); + ui->jsonPath->setText(fileName); + + loadConfigurationFromPath(); +} + +void SimulationDialog::on_simulateButton_clicked() +{ + saveConfiguration(temporaryConfigurationFile); + + ui->tabWidget->setCurrentWidget(ui->outputTab); + ui->progressBar->setEnabled(true); + ui->progressBar->setValue(0); + + showStopButton(true); + + // Spawn the DRAMSys process + simulatorProcess = new QProcess(this); + + QObject::connect(simulatorProcess, &QIODevice::readyRead, this, + [=] + { + QByteArray msg = simulatorProcess->read(4096); + msg = msg.trimmed(); + processMessage(msg.toStdString()); + }); + + QObject::connect(simulatorProcess, QOverload::of(&QProcess::finished), this, + [=](int exitCode, QProcess::ExitStatus exitStatus) + { + Q_UNUSED(exitStatus) + + showStopButton(false); + + // Clear all the contents so that the user is not asked + // next time to overwrite the temp file. + temporaryConfigurationFile.resize(0); + + if (exitCode == 0) + { + ui->progressBar->setValue(100); + + QMessageBox msgBox; + msgBox.setText("Simulation done."); + msgBox.setInformativeText("Do you want to open the results?"); + msgBox.setStandardButtons(QMessageBox::Open | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Open); + int ret = msgBox.exec(); + + if (ret == QMessageBox::Open) + { + auto results = getSimulationResults(); + openSimulationResults(results); + } + } + }); + + simulatorProcess->setWorkingDirectory(ui->outputDirLineEdit->text()); + simulatorProcess->start(ui->dramSysPath->text(), QStringList(temporaryConfigurationFile.fileName())); +} + +void SimulationDialog::on_reloadButton_clicked() +{ + loadConfigurationFromPath(); + + ui->outputPlainTextEdit->clear(); +} + +void SimulationDialog::on_saveButton_clicked() +{ + QFile file(ui->jsonPath->text()); + saveConfiguration(file); +} + +void SimulationDialog::on_stopButton_clicked() +{ + if (simulatorProcess) + simulatorProcess->terminate(); +} + +void SimulationDialog::showStopButton(bool val) +{ + ui->simulateButton->setVisible(!val); + ui->stopButton->setVisible(val); +} + +void SimulationDialog::saveConfiguration(QFile &file) +{ + if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) + return; + + if (file.size() != 0) + { + QMessageBox msgBox; + msgBox.setText("The configuration file will be overwritten."); + msgBox.setInformativeText("Do you want to save your changes?"); + msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Save); + int ret = msgBox.exec(); + + if (ret != QMessageBox::Save) + return; + } + + QTextStream out(&file); + + loadConfigurationFromTextFields(); + + std::string dump = DRAMSysConfiguration::dump(configuration, 4); + out << dump.c_str(); +} + +void SimulationDialog::processMessage(const std::string &msg) +{ + // Get percentages + QRegularExpression re("(\\d+(\\.\\d+)?|\\.\\d+) ?%"); + QRegularExpressionMatch match = re.match(msg.c_str()); + + if (match.hasMatch()) + { + unsigned int percentage = match.captured(1).toUInt(); + + ui->progressBar->setValue(percentage); + } + + ui->outputPlainTextEdit->appendPlainText(msg.c_str()); +} + +void SimulationDialog::loadConfigurationFromTextFields() +{ + using namespace DRAMSysConfiguration; + + AddressMapping addressMapping; + McConfig mcConfig; + MemSpec memSpec; + SimConfig simConfig; + std::string simulationId; + Optional thermalConfig; + Optional traceSetup; + + simulationId = ui->simulationIdLineEdit->text().toStdString(); + + try + { + from_dump(ui->addressMappingTextEdit->toPlainText().toStdString(), addressMapping); + from_dump(ui->mcConfigTextEdit->toPlainText().toStdString(), mcConfig); + from_dump(ui->memSpecTextEdit->toPlainText().toStdString(), memSpec); + from_dump(ui->simConfigTextEdit->toPlainText().toStdString(), simConfig); + + if (!ui->thermalConfigTextEdit->toPlainText().toStdString().empty()) + from_dump(ui->thermalConfigTextEdit->toPlainText().toStdString(), thermalConfig.setByReference()); + + if (!ui->traceSetupTextEdit->toPlainText().toStdString().empty()) + from_dump(ui->traceSetupTextEdit->toPlainText().toStdString(), traceSetup.setByReference()); + } + catch (const std::exception &e) + { + qWarning() << "Error while parsing json:" << e.what(); + return; + } + + configuration = DRAMSysConfiguration::Configuration{addressMapping, mcConfig, memSpec, simConfig, + simulationId, thermalConfig, traceSetup}; + + loadConfiguration(); +} + +void SimulationDialog::loadConfigurationFromPath() +{ + QFileInfo fileInfo(ui->jsonPath->text()); + + if (!fileInfo.isFile()) + return; + + try + { + configuration = DRAMSysConfiguration::from_path(ui->jsonPath->text().toStdString()); + } + catch (const std::exception &e) + { + qWarning() << "Error while parsing json:" << e.what(); + return; + } + + loadConfiguration(); +} + +void SimulationDialog::loadConfiguration() +{ + ui->simulationIdLabel->setEnabled(true); + ui->simulationId->setEnabled(true); + ui->simulationId->setText(configuration.simulationId.c_str()); + + ui->simulationIdLineEdit->setText(configuration.simulationId.c_str()); + + loadSimConfig(); + loadMcConfig(); + loadMemSpec(); + loadAddressMapping(); + loadThermalConfig(); + loadTraceSetup(); + loadPreview(); +} + +void SimulationDialog::loadSimConfig() +{ + ui->simConfigTextEdit->clear(); + + std::string dump = DRAMSysConfiguration::dump(configuration.simConfig, 4); + ui->simConfigTextEdit->setText(dump.c_str()); +} + +void SimulationDialog::loadMcConfig() +{ + ui->mcConfigTextEdit->clear(); + + std::string dump = DRAMSysConfiguration::dump(configuration.mcConfig, 4); + ui->mcConfigTextEdit->setText(dump.c_str()); +} + +void SimulationDialog::loadMemSpec() +{ + ui->memSpecTextEdit->clear(); + + std::string dump = DRAMSysConfiguration::dump(configuration.memSpec, 4); + ui->memSpecTextEdit->setText(dump.c_str()); +} + +void SimulationDialog::loadAddressMapping() +{ + ui->addressMappingTextEdit->clear(); + + std::string dump = DRAMSysConfiguration::dump(configuration.addressMapping, 4); + ui->addressMappingTextEdit->setText(dump.c_str()); +} + +void SimulationDialog::loadThermalConfig() +{ + ui->thermalConfigTextEdit->clear(); + + if (configuration.thermalConfig.isValid()) + { + std::string dump = DRAMSysConfiguration::dump(configuration.thermalConfig.getValue(), 4); + ui->thermalConfigTextEdit->setText(dump.c_str()); + } +} + +void SimulationDialog::loadTraceSetup() +{ + ui->traceSetupTextEdit->clear(); + + if (configuration.traceSetup.isValid()) + { + std::string dump = DRAMSysConfiguration::dump(configuration.traceSetup.getValue(), 4); + ui->traceSetupTextEdit->setText(dump.c_str()); + } +} + +void SimulationDialog::loadPreview() +{ + ui->previewTextEdit->clear(); + + std::string dump = DRAMSysConfiguration::dump(configuration, 4); + ui->previewTextEdit->setText(dump.c_str()); +} + +QFileInfoList SimulationDialog::getSimulationResults() +{ + QFileInfoList list; + + // Get the path where the tracefiles are located + QDir baseDir(ui->outputDirLineEdit->text()); + + for (const auto &fileInfo : baseDir.entryInfoList()) + { + if (fileInfo.baseName().startsWith(configuration.simulationId.c_str())) + { + // Dont open tracefiles that are older than a few seconds + if (fileInfo.metadataChangeTime().secsTo(QDateTime::currentDateTime()) > 30) + continue; + + list << fileInfo; + } + } + + return list; +} + +void SimulationDialog::openSimulationResults(const QFileInfoList &fileInfos) +{ + for (const auto &fileInfo : fileInfos) + openFileRequested(fileInfo.absoluteFilePath()); +} diff --git a/DRAMSys/traceAnalyzer/simulationdialog.h b/DRAMSys/traceAnalyzer/simulationdialog.h new file mode 100644 index 00000000..c26fda33 --- /dev/null +++ b/DRAMSys/traceAnalyzer/simulationdialog.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2021s, Technische Universität Kaiserslautern + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: + * Derek Christ + */ + +#ifndef SIMULATIONDIALOG_H +#define SIMULATIONDIALOG_H + +#include "ui_simulationdialog.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace Ui +{ +class SimulationDialog; +} + +class SimulationDialog : public QWidget +{ + Q_OBJECT + +public: + explicit SimulationDialog(QWidget *parent = nullptr); + +signals: + void openFileRequested(const QString &path); + +private Q_SLOTS: + void on_browseDramSysButton_clicked(); + void on_browseConfigButton_clicked(); + void on_simulateButton_clicked(); + void on_reloadButton_clicked(); + void on_saveButton_clicked(); + void on_stopButton_clicked(); + +private: + void loadConfigurationFromPath(); + void loadConfigurationFromTextFields(); + + void loadConfiguration(); + void loadSimConfig(); + void loadMcConfig(); + void loadMemSpec(); + void loadAddressMapping(); + void loadThermalConfig(); + void loadTraceSetup(); + void loadPreview(); + + void showStopButton(bool val); + void saveConfiguration(QFile &file); + void processMessage(const std::string &msg); + + QFileInfoList getSimulationResults(); + void openSimulationResults(const QFileInfoList &fileInfos); + + QTemporaryFile temporaryConfigurationFile; + DRAMSysConfiguration::Configuration configuration; + + QPointer simulatorProcess; + + Ui::SimulationDialog *ui; +}; + +#endif diff --git a/DRAMSys/traceAnalyzer/simulationdialog.ui b/DRAMSys/traceAnalyzer/simulationdialog.ui new file mode 100644 index 00000000..4041c770 --- /dev/null +++ b/DRAMSys/traceAnalyzer/simulationdialog.ui @@ -0,0 +1,345 @@ + + + SimulationDialog + + + + 0 + 0 + 884 + 522 + + + + + + + Simulation + + + + + + Simulation + + + + + + + + Browse... + + + + + + + Path to Json configuration... + + + + + + + Path to DRAMSys... + + + + + + + DRAMSys: + + + + + + + Browse... + + + + + + + Base configuration: + + + + + + + Path to output directory... + + + + + + + Browse... + + + + + + + Output directory: + + + + + + + + + + + false + + + Simulation Id: + + + + + + + false + + + + + + + + + + + + + + false + + + 0 + + + + + + + Start Simulation + + + + + + + Stop Simulation + + + + + + + + + + + + 0 + + + + SimConfig + + + + + + + + + + + + + + McConfig + + + + + + + + + + + + + + MemSpec + + + + + + + + + + + + + + ThermalConfig + + + + + + + + + + + + + + TraceSetup + + + + + + + + + + + + + + AddressMapping + + + + + + + + + + + + + + Preview Configuration + + + + + + + + + true + + + + + + + + Output + + + + + + + + + QPlainTextEdit::NoWrap + + + true + + + + + + + + + + + + + Reload + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Simulation Id + + + + + + + Save + + + false + + + + + + + Close + + + + + + + + + + + closeButton + clicked() + SimulationDialog + close() + + + 836 + 507 + + + 830 + 575 + + + + + diff --git a/DRAMSys/traceAnalyzer/traceanalyzer.cpp b/DRAMSys/traceAnalyzer/traceanalyzer.cpp index b0159918..1cc0db53 100644 --- a/DRAMSys/traceAnalyzer/traceanalyzer.cpp +++ b/DRAMSys/traceAnalyzer/traceanalyzer.cpp @@ -37,8 +37,10 @@ */ #include "traceanalyzer.h" +#include "simulationdialog.h" #include "tracefiletab.h" #include "ui_traceanalyzer.h" + #include #include #include @@ -281,3 +283,13 @@ void TraceAnalyzer::closeEvent(QCloseEvent *event) event->accept(); } + +void TraceAnalyzer::on_actionSimulate_triggered() +{ + SimulationDialog *simulationDialog = new SimulationDialog(this); + simulationDialog->setWindowFlag(Qt::Window); + + QObject::connect(simulationDialog, &SimulationDialog::openFileRequested, this, &TraceAnalyzer::openTracefileTab); + + simulationDialog->show(); +} diff --git a/DRAMSys/traceAnalyzer/traceanalyzer.h b/DRAMSys/traceAnalyzer/traceanalyzer.h index a2aab12d..b5e8cdd1 100644 --- a/DRAMSys/traceAnalyzer/traceanalyzer.h +++ b/DRAMSys/traceAnalyzer/traceanalyzer.h @@ -97,6 +97,7 @@ private Q_SLOTS: void on_actionClose_triggered(); void on_actionClose_all_triggered(); void on_actionAbout_triggered(); + void on_actionSimulate_triggered(); public Q_SLOTS: void statusChanged(const QString &message); diff --git a/DRAMSys/traceAnalyzer/traceanalyzer.ui b/DRAMSys/traceAnalyzer/traceanalyzer.ui index f382563d..5fec0849 100644 --- a/DRAMSys/traceAnalyzer/traceanalyzer.ui +++ b/DRAMSys/traceAnalyzer/traceanalyzer.ui @@ -78,7 +78,14 @@ + + + &Run + + + + @@ -225,6 +232,14 @@ Save &as... + + + + + + &Simulate... + +