HAL  v4.5.0-251-g305763a14
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
gatelibrary_wizard.cpp
Go to the documentation of this file.
2 
13 
14 #include <QGridLayout>
15 
16 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
17 #define SKIP_EMPTY_PARTS Qt::SkipEmptyParts
18 #else
19 #define SKIP_EMPTY_PARTS QString::SkipEmptyParts
20 #endif
21 
22 namespace hal
23 {
24  GateLibraryWizard::GateLibraryWizard(GateLibrary* gateLibrary, GateType* gateType, QWidget* parent) : QWizard(parent)
25  {
26  mEditMode = false;
27 
28  generalInfoPage = new GeneralInfoWizardPage(gateLibrary, this);
29  pinsPage = new PinsWizardPage(this);
30  ffPage = new FlipFlopWizardPage(this);
31  boolPage = new BoolWizardPage(this);
32  latchPage = new LatchWizardPage(this);
33  lutPage = new LUTWizardPage(this);
34  initPage = new InitWizardPage(this);
35  ramPage = new RAMWizardPage(this);
36  ramportPage = new RAMPortWizardPage(this);
37  statePage = new StateWizardPage(this);
38 
39  setPage(GeneralInfo, generalInfoPage);
40  setPage(Pin, pinsPage);
41  setPage(FlipFlop, ffPage);
42  setPage(Latch, latchPage);
43  setPage(LUT, lutPage);
44  setPage(RAM, ramPage);
45  setPage(RAMPort, ramportPage);
46  setPage(Init, initPage);
47  setPage(State, statePage);
48  setPage(BoolFunc, boolPage);
49 
50  mGateLibrary = gateLibrary;
51  mGateType = gateType;
52  mPinModel = new PinModel(this, true);
53  mWasEdited = false;
54 
55  if (mGateType == nullptr)
56  {
57  setWindowTitle("Create new gate type");
58  setButtonText(WizardButton::FinishButton, "Finish");
59  }
60  else
61  {
62  setWindowTitle("Modify gate type " + QString::fromStdString(mGateType->get_name()));
63  setButtonText(WizardButton::FinishButton, "Save changes");
64 
65  generalInfoPage->setData(QString::fromStdString(mGateType->get_name()), mGateType->get_property_list());
66  ffPage->setData(mGateType);
67  latchPage->setData(mGateType);
68  lutPage->setData(mGateType);
69  initPage->setData(mGateType);
70  ramPage->setData(mGateType);
71  ramportPage->setData(mGateType);
72  statePage->setData(mGateType);
73  boolPage->setData(mGateType);
74  }
75  mTitle = windowTitle();
76 
77  connect(generalInfoPage, &GeneralInfoWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
78  connect(pinsPage, &PinsWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
79  connect(ffPage, &FlipFlopWizardPage::hasChanged, this, &GateLibraryWizard::handleWasEdited);
80  connect(boolPage, &BoolWizardPage::hasChanged, this, &GateLibraryWizard::handleWasEdited);
81  connect(latchPage, &LatchWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
82  connect(lutPage, &LUTWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
83  connect(initPage, &InitWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
84  connect(ramPage, &RAMWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
85  connect(ramportPage, &RAMPortWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
86  connect(statePage, &StateWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
87  }
88 
90  {
91  //Convert QStringList to std::set
92  std::set<GateTypeProperty> properties_set;
93  for (GateTypeProperty prop : generalInfoPage->getProperties())
94  {
95  properties_set.insert(prop);
96  }
97 
98  if (mGateType)
99  {
100  mGateType = mGateLibrary->replace_gate_type(mGateType->get_id(), generalInfoPage->getName().toStdString(), properties_set, setComponents());
101  //Set pingroups and pins
102  for (PinItem* pingroup : getPingroups())
103  {
104  std::vector<GatePin*> gatepins;
105  for (auto it : pingroup->getChildren())
106  {
107  PinItem* pin = static_cast<PinItem*>(it);
109  {
110  auto res = mGateType->create_pin(pin->getName().toStdString(), pin->getDirection(), pin->getPinType());
111  if (res.is_ok())
112  {
113  gatepins.push_back(res.get());
114  }
115  }
116  }
117  if (pingroup->getItemType() != PinItem::TreeItemType::GroupCreator)
118  {
119  mGateType->create_pin_group(pingroup->getName().toStdString(), gatepins, pingroup->getDirection(), pingroup->getPinType());
120  }
121  }
122 
123  //TODO: Set boolean functions without adding the same double
124  //also: boolean functions may be removed
125  mGateType->add_boolean_functions(boolPage->getBoolFunctions());
126  }
127  else
128  {
129  //Set name, properties and the parent component
130  mNewGateType = mGateLibrary->create_gate_type(generalInfoPage->getName().toStdString(), properties_set, setComponents());
131  //Set pingroups and pins
132  for (PinItem* pingroup : getPingroups())
133  {
134  std::vector<GatePin*> gatepins;
135  for (auto it : pingroup->getChildren())
136  {
137  PinItem* pin = static_cast<PinItem*>(it);
139  {
140  auto res = mNewGateType->create_pin(pin->getName().toStdString(), pin->getDirection(), pin->getPinType());
141  if (res.is_ok())
142  {
143  gatepins.push_back(res.get());
144  }
145  }
146  }
147  if (pingroup->getItemType() != PinItem::TreeItemType::GroupCreator)
148  {
149  mNewGateType->create_pin_group(pingroup->getName().toStdString(), gatepins, pingroup->getDirection(), pingroup->getPinType());
150  }
151  }
152 
153  //Set boolean functions
154  mNewGateType->add_boolean_functions(boolPage->getBoolFunctions());
155  }
156  this->close();
157 
158  if (mWasEdited)
159  {
161  }
163  }
164 
165  void GateLibraryWizard::handleWasEdited()
166  {
167  mWasEdited = true;
168  setWindowTitle(mTitle + " *");
169  }
170 
172  {
173  return mNewGateType;
174  }
175 
177  {
178  return mPinModel->getPinGroups();
179  }
180 
182  {
183  if (!generalInfoPage->getProperties().contains(GateTypeProperty::c_lut))
184  {
185  return false;
186  }
187  return pin->getPinType() == PinType::lut;
188  }
189 
191  {
192  for (PinItem* pin : mPinModel->getOutputPins())
193  {
194  if (!isDefinedByLut(pin))
195  {
196  return true;
197  }
198  }
199  return false;
200  }
201 
202  std::unique_ptr<GateTypeComponent> GateLibraryWizard::setComponents()
203  {
204  std::unique_ptr<GateTypeComponent> parentComponent;
205  for (GateTypeProperty prop : generalInfoPage->getProperties())
206  {
207  //Set components
208  if (prop == GateTypeProperty::c_lut)
209  {
210  const bool ascending = lutPage->mAscending->isChecked();
211  std::vector<std::string> input_pin_names;
212  for (PinItem* pi : mPinModel->getInputPins())
213  input_pin_names.push_back(pi->getName().toStdString());
214  std::unordered_map<std::string, LUTComponent::LUTOutputConfig> lut_configs;
215  for (const auto& entry : lutPage->getOutputPinConfigs())
216  {
217  lut_configs.emplace(entry.pinName.toStdString(),
218  LUTComponent::LUTOutputConfig(entry.initIdentifier.toStdString(), entry.bitOffset, entry.bitCount, ascending, input_pin_names));
219  }
220  parentComponent = LUTComponent::create(std::move(lut_configs));
221  }
222  else if (prop == GateTypeProperty::ff)
223  {
224  std::vector<std::string> identifiers;
225  for (QString id : initPage->mIdentifiers->toPlainText().split('\n', SKIP_EMPTY_PARTS))
226  {
227  identifiers.push_back(id.toStdString());
228  }
229  std::unique_ptr<GateTypeComponent> init_component = InitComponent::create(initPage->mCategory->text().toStdString(), identifiers);
230  std::unique_ptr<GateTypeComponent> state_component =
231  StateComponent::create(std::move(init_component), statePage->mStateIdentifier->text().toStdString(), statePage->mNegStateIdentifier->text().toStdString());
232  BooleanFunction next_state_bf;
233  BooleanFunction clock_bf;
234 
235  auto next_state_res = BooleanFunction::from_string(ffPage->mNextState->text().toStdString());
236  auto clock_bf_res = BooleanFunction::from_string(ffPage->mClock->text().toStdString());
237 
238  if (next_state_res.is_ok())
239  {
240  next_state_bf = next_state_res.get();
241  }
242  if (clock_bf_res.is_ok())
243  {
244  clock_bf = clock_bf_res.get();
245  }
246 
247  std::unique_ptr<GateTypeComponent> component = FFComponent::create(std::move(state_component), next_state_bf, clock_bf);
248  FFComponent* ff_component = component->convert_to<FFComponent>();
249 
250  BooleanFunction async_reset;
251  auto async_reset_res = BooleanFunction::from_string(ffPage->mAReset->text().toStdString());
252  if (async_reset_res.is_ok())
253  {
254  async_reset = async_reset_res.get();
255  }
256  ff_component->set_async_reset_function(async_reset);
257 
258  BooleanFunction async_set;
259  auto async_set_res = BooleanFunction::from_string(ffPage->mASet->text().toStdString());
260  if (async_set_res.is_ok())
261  {
262  async_set = async_set_res.get();
263  }
264  ff_component->set_async_set_function(async_set);
265 
266  const auto behav_state = enum_from_string<AsyncSetResetBehavior>(ffPage->mIntState->text().toStdString(), AsyncSetResetBehavior::undef);
267  const auto behav_neg_state = enum_from_string<AsyncSetResetBehavior>(ffPage->mNegIntState->text().toStdString(), AsyncSetResetBehavior::undef);
268  ff_component->set_async_set_reset_behavior(behav_state, behav_neg_state);
269  parentComponent = std::move(component);
270  }
271  else if (prop == GateTypeProperty::latch)
272  {
273  std::unique_ptr<GateTypeComponent> state_component =
274  StateComponent::create(nullptr, statePage->mStateIdentifier->text().toStdString(), statePage->mNegStateIdentifier->text().toStdString());
275  std::unique_ptr<GateTypeComponent> component = LatchComponent::create(std::move(state_component));
276  LatchComponent* latch_component = component->convert_to<LatchComponent>();
277 
278  auto data_in_res = BooleanFunction::from_string(latchPage->mDataIn->text().toStdString());
279  auto enable_res = BooleanFunction::from_string(latchPage->mEnableOn->text().toStdString());
280 
281  if (data_in_res.is_ok())
282  {
283  latch_component->set_data_in_function(data_in_res.get());
284  }
285  if (enable_res.is_ok())
286  {
287  latch_component->set_enable_function(enable_res.get());
288  }
289 
290  BooleanFunction async_reset;
291  auto async_reset_res = BooleanFunction::from_string(latchPage->mAReset->text().toStdString());
292  if (async_reset_res.is_ok())
293  {
294  async_reset = async_reset_res.get();
295  }
296  latch_component->set_async_reset_function(async_reset);
297 
298  BooleanFunction async_set;
299  auto async_set_res = BooleanFunction::from_string(latchPage->mASet->text().toStdString());
300  if (async_set_res.is_ok())
301  {
302  async_set = async_set_res.get();
303  }
304  latch_component->set_async_set_function(async_set);
305 
306  const auto behav_state = enum_from_string<AsyncSetResetBehavior>(latchPage->mIntState->text().toStdString(), AsyncSetResetBehavior::undef);
307  const auto behav_neg_state = enum_from_string<AsyncSetResetBehavior>(latchPage->mNegIntState->text().toStdString(), AsyncSetResetBehavior::undef);
308  latch_component->set_async_set_reset_behavior(behav_state, behav_neg_state);
309 
310  parentComponent = std::move(component);
311  }
312  else if (prop == GateTypeProperty::ram)
313  {
314  std::unique_ptr<GateTypeComponent> sub_component = nullptr;
315  std::vector<std::string> identifiers;
316  for (QString id : initPage->mIdentifiers->toPlainText().split('\n', SKIP_EMPTY_PARTS))
317  {
318  identifiers.push_back(id.toStdString());
319  }
320 
321  for (RAMPortWizardPage::RAMPort rpEdit : ramportPage->getRamPorts())
322  {
323  BooleanFunction clocked_on_bf;
324  auto clocked_on_res = BooleanFunction::from_string(rpEdit.clockFunction->text().toStdString());
325  if (clocked_on_res.is_ok())
326  {
327  clocked_on_bf = clocked_on_res.get();
328  }
329 
330  BooleanFunction enabled_on_bf;
331  auto enabled_on_res = BooleanFunction::from_string(rpEdit.enableFunciton->text().toStdString());
332  if (enabled_on_res.is_ok())
333  {
334  enabled_on_bf = enabled_on_res.get();
335  }
336 
337  sub_component = RAMPortComponent::create(
338  std::move(sub_component), rpEdit.dataGroup->text().toStdString(), rpEdit.addressGroup->text().toStdString(), clocked_on_bf, enabled_on_bf, rpEdit.isWritePort->isChecked());
339  }
340  parentComponent = RAMComponent::create(std::move(sub_component), ramPage->mBitSize->text().toInt(), identifiers);
341  }
342  }
343  return std::move(parentComponent);
344  }
345 
347  {
348  const QList<GateTypeProperty> properties = generalInfoPage->getProperties();
349 
350  switch (currentId())
351  {
352  case GeneralInfo:
353  return Pin;
354  case Pin:
355  if (properties.contains(GateTypeProperty::ff) || properties.contains(GateTypeProperty::latch))
356  {
357  return State;
358  }
359  else if (properties.contains(GateTypeProperty::c_lut))
360  {
361  return LUT;
362  }
363  else if (properties.contains(GateTypeProperty::ram))
364  {
365  return RAM;
366  }
367  return BoolFunc;
368  case State:
369  if (properties.contains(GateTypeProperty::ff))
370  {
371  return FlipFlop;
372  }
373  else if (properties.contains(GateTypeProperty::latch))
374  {
375  return Latch;
376  }
377  else if (properties.contains(GateTypeProperty::c_lut))
378  {
379  return LUT;
380  }
381  else if (properties.contains(GateTypeProperty::ram))
382  {
383  return Init;
384  }
385  return BoolFunc;
386  case FlipFlop:
387  if (properties.contains(GateTypeProperty::latch))
388  {
389  return Latch;
390  }
391  else if (properties.contains(GateTypeProperty::c_lut))
392  {
393  return LUT;
394  }
395  else if (properties.contains(GateTypeProperty::ram))
396  {
397  return RAM;
398  }
399  return Init;
400  case Latch:
401  if (properties.contains(GateTypeProperty::c_lut))
402  {
403  return LUT;
404  }
405  else if (properties.contains(GateTypeProperty::ram))
406  {
407  return RAM;
408  }
409  return Init;
410  case LUT:
411  if (properties.contains(GateTypeProperty::ram))
412  {
413  return RAM;
414  }
415  else if (requiresBooleanFunctions())
416  {
417  return BoolFunc;
418  }
419  return -1;
420  case RAM:
421  return RAMPort;
422  case RAMPort:
423  if (properties.contains(GateTypeProperty::ff) || properties.contains(GateTypeProperty::latch))
424  {
425  return State;
426  }
427  return Init;
428  case Init:
430  {
431  return -1;
432  }
433  return BoolFunc;
434  case BoolFunc:
435  default:
436  return -1;
437  }
438  }
439 } // namespace hal
std::unordered_map< std::string, BooleanFunction > getBoolFunctions()
void setData(GateType *gate)
static Result< BooleanFunction > from_string(const std::string &expression)
void set_async_set_reset_behavior(const AsyncSetResetBehavior behav_state, const AsyncSetResetBehavior behav_neg_state)
void set_async_set_function(const BooleanFunction &async_set_bf)
static std::unique_ptr< FFComponent > create(std::unique_ptr< GateTypeComponent > component, const BooleanFunction &next_state_bf, const BooleanFunction &clock_bf)
void set_async_reset_function(const BooleanFunction &async_reset_bf)
void setData(GateType *gate)
GateType * replace_gate_type(u32 id, const std::string &name, std::set< GateTypeProperty > properties={GateTypeProperty::combinational}, std::unique_ptr< GateTypeComponent > component=nullptr)
GateType * create_gate_type(const std::string &name, std::set< GateTypeProperty > properties={GateTypeProperty::combinational}, std::unique_ptr< GateTypeComponent > component=nullptr)
bool isDefinedByLut(const PinItem *pin) const
int nextId() const override
QList< PinItem * > getPingroups()
std::unique_ptr< GateTypeComponent > setComponents()
GateLibraryWizard(GateLibrary *gateLibrary, GateType *gateType=nullptr, QWidget *parent=nullptr)
friend class GeneralInfoWizardPage
Result< GatePin * > create_pin(const u32 id, const std::string &name, PinDirection direction, PinType type=PinType::none, bool create_group=true)
Definition: gate_type.cpp:157
std::vector< GateTypeProperty > get_property_list() const
Definition: gate_type.cpp:79
const std::string & get_name() const
Definition: gate_type.cpp:64
Result< PinGroup< GatePin > * > create_pin_group(const u32 id, const std::string &name, const std::vector< GatePin * > pins={}, PinDirection direction=PinDirection::none, PinType type=PinType::none, bool ascending=true, i32 start_index=0, bool delete_empty_groups=true)
Definition: gate_type.cpp:369
void add_boolean_functions(const std::unordered_map< std::string, BooleanFunction > &functions)
Definition: gate_type.cpp:706
u32 get_id() const
Definition: gate_type.cpp:59
QList< GateTypeProperty > getProperties() const
void setData(QString name, const std::vector< GateTypeProperty > &properties)
static std::unique_ptr< InitComponent > create(const std::string &init_category, const std::vector< std::string > &init_identifiers)
void setData(GateType *gate)
static std::unique_ptr< LUTComponent > create(std::unordered_map< std::string, LUTOutputConfig > configs={})
void setData(GateType *gate)
QVector< OutputPinEntry > getOutputPinConfigs() const
void set_async_reset_function(const BooleanFunction &async_reset_bf)
void set_async_set_reset_behavior(AsyncSetResetBehavior behav_state, AsyncSetResetBehavior behav_neg_state)
void set_enable_function(const BooleanFunction &enable_bf)
void set_async_set_function(const BooleanFunction &async_set_bf)
void set_data_in_function(const BooleanFunction &data_in_bf)
static std::unique_ptr< LatchComponent > create(std::unique_ptr< GateTypeComponent > component)
void setData(GateType *gate)
An item in the PinModel.
Definition: pin_item.h:48
QString getName() const
Definition: pin_item.cpp:81
PinDirection getDirection() const
Definition: pin_item.cpp:96
TreeItemType getItemType() const
Definition: pin_item.cpp:132
PinType getPinType() const
Definition: pin_item.cpp:86
QList< PinItem * > getInputPins()
Definition: pin_model.cpp:733
QList< PinItem * > getOutputPins()
Definition: pin_model.cpp:748
QList< PinItem * > getPinGroups() const
Definition: pin_model.cpp:636
static std::unique_ptr< RAMComponent > create(std::unique_ptr< GateTypeComponent > component, const u32 bit_size, const std::vector< std::string > &init_identifiers={})
static std::unique_ptr< RAMPortComponent > create(std::unique_ptr< GateTypeComponent > component, const std::string &data_group, const std::string &addr_group, const BooleanFunction &clock_bf, const BooleanFunction &enable_bf, bool is_write)
QList< RAMPort > getRamPorts()
void setData(GateType *gate)
void setData(GateType *gate)
static std::unique_ptr< StateComponent > create(std::unique_ptr< GateTypeComponent > component, const std::string &state_identifier, const std::string &neg_state_identifier)
void setData(GateType *gate)
#define SKIP_EMPTY_PARTS
Definition: defines.h:45
FileStatusManager * gFileStatusManager
Definition: plugin_gui.cpp:85
bool ascending
bool isChecked() const const
bool contains(const T &value) const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QString fromStdString(const std::string &str)
std::string toStdString() const const
QString toPlainText() const const
bool close()
void setWindowTitle(const QString &)
void setButtonText(QWizard::WizardButton which, const QString &text)
void setPage(int id, QWizardPage *page)
void completeChanged()