HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
plugin_netlist_simulator_controller.cpp
Go to the documentation of this file.
8 #include <QJsonObject>
9 #include <QJsonArray>
10 #include <QJsonDocument>
11 #include <QDebug>
12 #include <QResource>
13 #include <QFile>
14 #include <QSettings>
15 #include <QDir>
16 #include <QCoreApplication>
17 
18 namespace hal
19 {
20  u32 NetlistSimulatorControllerPlugin::sMaxControllerId = 0;
21  SimulationSettings* NetlistSimulatorControllerPlugin::sSimulationSettings = nullptr;
22  SimulatorSerializer* NetlistSimulatorControllerPlugin::sSimulatorSerializer = nullptr;
23 
25  : ProjectSerializer("simulator"), mNetlist(nullptr)
26  {;}
27 
28  std::string SimulatorSerializer::serialize(Netlist* netlist, const std::filesystem::path& savedir, bool isAutosave)
29  {
30  Q_UNUSED(netlist);
31  Q_UNUSED(isAutosave);
32  QString simFilename("simulator.json");
33  QFile simFile(QDir(QString::fromStdString(savedir.string())).absoluteFilePath(simFilename));
34  if (!simFile.open(QIODevice::WriteOnly)) return std::string();
35 
36  QJsonObject simObj;
37  QJsonArray simArr;
38 
40  {
41  QJsonObject simEntry;
42  simEntry["id"] = (int) ctrl->get_id();
43  simEntry["name"] = ctrl->name();
44  std::string absoluteWorkingDir = ctrl->get_working_directory();
45  std::filesystem::path relProjdir = ProjectManager::instance()->get_project_directory().get_relative_file_path(ctrl->get_working_directory());
46  simEntry["workdir"] = QString::fromStdString(relProjdir.string());
47  simArr.append(simEntry);
48  }
49  simObj["simulator"] = simArr;
50 
51  simFile.write(QJsonDocument(simObj).toJson(QJsonDocument::Compact));
52 
53  return simFilename.toStdString();
54 
55  }
56 
57  void SimulatorSerializer::deserialize(Netlist* netlist, const std::filesystem::path& loaddir)
58  {
59  mNetlist = netlist;
60  if (!loaddir.empty())
61  mProjDir = QDir(QString::fromStdString(loaddir.string()));
63  }
64 
65  std::vector<std::unique_ptr<NetlistSimulatorController>> SimulatorSerializer::restore()
66  {
67  std::vector<std::unique_ptr<NetlistSimulatorController>> retval;
69  std::string relname = pm->get_filename(m_name);
70  if (relname.empty()) return retval;
71 
72  NetlistSimulatorControllerPlugin* ctrlPlug = static_cast<NetlistSimulatorControllerPlugin*>(plugin_manager::get_plugin_instance("netlist_simulator_controller"));
73  if (!ctrlPlug) return retval;
74  if (mProjDir.isEmpty())
76 
77 
78  QFile simFile(mProjDir.absoluteFilePath(QString::fromStdString(relname)));
79  if (!simFile.open(QIODevice::ReadOnly))
80  return retval;
81  QJsonDocument simDoc = QJsonDocument::fromJson(simFile.readAll());
82  const QJsonObject& simObj = simDoc.object();
83 
84  if (simObj.contains("simulator") && simObj["simulator"].isArray())
85  {
86  QJsonArray simArr = simObj["simulator"].toArray();
87  int n = simArr.size();
88  for (int i = 0; i < n; i++)
89  {
90  QJsonObject simEntry = simArr.at(i).toObject();
91  QString workdir = simEntry["workdir"].toString();
92  if (workdir.isEmpty()) continue;
93  if (QFileInfo(workdir).isRelative()) workdir =
94  QString::fromStdString(ProjectManager::instance()->get_project_directory().get_filename(workdir.toStdString()).string());
95  QString contrFile = QDir(workdir).absoluteFilePath("netlist_simulator_controller.json");
96  retval.push_back(ctrlPlug->restore_simulator_controller(mNetlist,contrFile.toStdString()));
97  }
98  }
99 
100  return retval;
101  }
102 
103  extern std::unique_ptr<BasePluginInterface> create_plugin_instance()
104  {
105  return std::make_unique<NetlistSimulatorControllerPlugin>();
106  }
107 
109  {
110  return std::string("netlist_simulator_controller");
111  }
112 
114  {
115  return std::string("0.7");
116  }
117 
119  {
120  return std::string("Non-GUI base plugin to control simulation");
121  }
122 
123  std::unique_ptr<NetlistSimulatorController> NetlistSimulatorControllerPlugin::create_simulator_controller(const std::string &nam, const std::string &workdir) const
124  {
125  NetlistSimulatorController* nsc = new NetlistSimulatorController(++sMaxControllerId, nam, workdir);
126  if (!nsc->is_legal_directory_name())
127  {
128  log_warning("simulation_plugin", "Invalid simulator working directory '{}' (hint: avoid spaces)", nsc->get_working_directory());
129  delete nsc;
130  return nullptr;
131  }
132  qApp->processEvents();
133  return std::unique_ptr<NetlistSimulatorController>(nsc);
134  }
135 
136  std::unique_ptr<NetlistSimulatorController> NetlistSimulatorControllerPlugin::restore_simulator_controller(Netlist* nl, const std::string &filename) const
137  {
138  NetlistSimulatorController* nsc = new NetlistSimulatorController(++sMaxControllerId,nl,filename);
139  if (nsc->get_working_directory().empty())
140  {
141  delete nsc;
142  return nullptr;
143  }
144  qApp->processEvents();
145  return std::unique_ptr<NetlistSimulatorController>(nsc);
146  }
147 
148  std::shared_ptr<NetlistSimulatorController> NetlistSimulatorControllerPlugin::simulator_controller_by_id(u32 id) const
149  {
151  if (!ctrl)
152  {
153  log_warning("simulation_plugin", "Simulation controller with ID={} not found in memory, will return nullptr", id);
154  return nullptr;
155  }
156  qApp->processEvents();
157  return std::shared_ptr<NetlistSimulatorController>(ctrl,[](void*){;});
158  }
159 
161  {
163  QResource::unregisterResource("simulator_resources.rcc");
166  if (mGuiExtensions)
167  {
168  delete mGuiExtensions;
169  mGuiExtensions = nullptr;
170  }
171  }
172 
174  {
175  // report simulation warnings and error messages not related to specific controller to common channel
176  mGuiExtensions = new GuiExtensionSimulator(this);
178  QResource::registerResource("simulator_resources.rcc");
180  sSimulationSettings = new SimulationSettings(userConfigDir.absoluteFilePath("simulationsettings.ini"));
182  }
183 
184  //----------------------------
185 
186  std::vector<PluginParameter> GuiExtensionSimulator::get_parameter() const
187  {
188  const char* colorLabel[] = {"Regular waveform", "Selected waveform", "Undefined value", "Background X", "Background 0", "Background 1"};
189  std::vector<PluginParameter> retval;
190  retval.push_back(PluginParameter(PluginParameter::TabName,"tab1","Global settings"));
191  retval.push_back(PluginParameter(PluginParameter::Integer,"tab1/max_mem","Max events to load into memory",QString::number(NetlistSimulatorControllerPlugin::sSimulationSettings->maxSizeLoadable()).toStdString()));
192  retval.push_back(PluginParameter(PluginParameter::Integer,"tab1/max_edit","Max events to load into editor",QString::number(NetlistSimulatorControllerPlugin::sSimulationSettings->maxSizeEditor()).toStdString()));
193  retval.push_back(PluginParameter(PluginParameter::ExistingDir,"tab1/base_dir","Base directory for simulation work directory"));
194  retval.push_back(PluginParameter(PluginParameter::TabName,"tab2","Engine parameter"));
195  retval.push_back(PluginParameter(PluginParameter::Dictionary,"tab2/par", "Engine parameter"));
196  retval.push_back(PluginParameter(PluginParameter::TabName,"tab3","Color settings"));
197  for (int i=0; i<SimulationSettings::MaxColorSetting; i++)
198  {
200  retval.push_back(
202  QString("tab3/col%1").arg(i).toStdString(),
203  std::string(colorLabel[i]),
205  }
206  retval.push_back(PluginParameter(PluginParameter::PushButton,"ok","Ok"));
207  return retval;
208  }
209 
210  void GuiExtensionSimulator::set_parameter(const std::vector<PluginParameter>& params)
211  {
212 
213  }
214 
215 } // namespace hal
std::vector< PluginParameter > get_parameter() const override
void set_parameter(const std::vector< PluginParameter > &params) override
std::shared_ptr< spdlog::logger > add_channel(const std::string &channel_name, const std::vector< std::shared_ptr< log_sink >> &sinks, const std::string &level="info")
Definition: log.cpp:100
static std::shared_ptr< log_sink > create_gui_sink()
Definition: log.cpp:274
static std::shared_ptr< log_sink > create_file_sink(const std::filesystem::path &file_name="", const bool truncate=false)
Definition: log.cpp:247
static std::shared_ptr< log_sink > create_stdout_sink(const bool colored=true)
Definition: log.cpp:216
static LogManager * get_instance(const std::filesystem::path &file_name="")
Definition: log.cpp:61
NetlistSimulatorController * controller(u32 id) const
static NetlistSimulatorControllerMap * instance()
std::unique_ptr< NetlistSimulatorController > create_simulator_controller(const std::string &nam=std::string(), const std::string &workdir=std::string()) const
std::shared_ptr< NetlistSimulatorController > simulator_controller_by_id(u32 id) const
std::unique_ptr< NetlistSimulatorController > restore_simulator_controller(Netlist *nl, const std::string &filename) const
std::filesystem::path get_relative_file_path(const std::string &filename) const
static ProjectManager * instance()
std::string get_filename(const std::string &serializer_name)
const ProjectDirectory & get_project_directory() const
std::vector< std::unique_ptr< NetlistSimulatorController > > restore()
std::string serialize(Netlist *netlist, const std::filesystem::path &savedir, bool isAutosave) override
void deserialize(Netlist *netlist, const std::filesystem::path &loaddir) override
uint32_t u32
Definition: defines.h:41
#define log_warning(channel,...)
Definition: log.h:76
BasePluginInterface * get_plugin_instance(const std::string &plugin_name, bool initialize=true, bool silent=false)
std::filesystem::path get_user_config_directory()
Definition: utils.cpp:172
Definition: defines.h:45
std::unique_ptr< BasePluginInterface > create_plugin_instance()
QString absoluteFilePath(const QString &fileName) const const
bool isEmpty(QDir::Filters filters) const const
virtual bool open(QIODevice::OpenMode mode) override
QByteArray readAll()
qint64 write(const char *data, qint64 maxSize)
void append(const QJsonValue &value)
QJsonValue at(int i) const const
int size() const const
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QJsonObject object() const const
bool contains(const QString &key) const const
QJsonObject toObject() const const
bool registerResource(const QString &rccFileName, const QString &mapRoot)
bool unregisterResource(const QString &rccFileName, const QString &mapRoot)
void sync()
QString fromStdString(const std::string &str)
bool isEmpty() const const
QString number(int n, int base)
void push_back(QChar ch)
std::string toStdString() const const