HAL
gatelibrary_wizard.cpp
Go to the documentation of this file.
8 
9 
10 #include <QGridLayout>
11 
12 #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
13 #define SKIP_EMPTY_PARTS Qt::SkipEmptyParts
14 #else
15 #define SKIP_EMPTY_PARTS QString::SkipEmptyParts
16 #endif
17 
18 namespace hal
19 {
20  GateLibraryWizard::GateLibraryWizard(GateLibrary *gateLibrary, GateType *gateType, QWidget* parent): QWizard(parent)
21  {
22  mEditMode = false;
23 
24  generalInfoPage = new GeneralInfoWizardPage(gateLibrary, this);
25  pinsPage = new PinsWizardPage(this);
26  ffPage = new FlipFlopWizardPage(this);
27  boolPage = new BoolWizardPage(this);
28  latchPage = new LatchWizardPage(this);
29  lutPage = new LUTWizardPage(this);
30  initPage = new InitWizardPage(this);
31  ramPage = new RAMWizardPage(this);
32  ramportPage = new RAMPortWizardPage(this);
33  statePage = new StateWizardPage(this);
34 
35  setPage(GeneralInfo, generalInfoPage);
36  setPage(Pin, pinsPage);
37  setPage(FlipFlop, ffPage);
38  setPage(Latch, latchPage);
39  setPage(LUT, lutPage);
40  setPage(RAM, ramPage);
41  setPage(RAMPort, ramportPage);
42  setPage(Init, initPage);
43  setPage(State, statePage);
44  setPage(BoolFunc, boolPage);
45 
46  mGateLibrary = gateLibrary;
47  mGateType = gateType;
48  mPinModel = new PinModel(this, true);
49  mWasEdited = false;
50 
51  if(mGateType == nullptr)
52  {
53  setWindowTitle("Create new gate type");
54  setButtonText(WizardButton::FinishButton, "Finish");
55  }
56  else
57  {
58  setWindowTitle("Modify gate type " + QString::fromStdString(mGateType->get_name()));
59  setButtonText(WizardButton::FinishButton, "Save changes");
60 
61  generalInfoPage->setData(QString::fromStdString(mGateType->get_name()), mGateType->get_property_list());
62  ffPage->setData(mGateType);
63  latchPage->setData(mGateType);
64  lutPage->setData(mGateType);
65  initPage->setData(mGateType);
66  ramPage->setData(mGateType);
67  ramportPage->setData(mGateType);
68  statePage->setData(mGateType);
69  boolPage->setData(mGateType);
70  }
71  mTitle = windowTitle();
72 
73  connect(generalInfoPage, &GeneralInfoWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
74  connect(pinsPage, &PinsWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
75  connect(ffPage, &FlipFlopWizardPage::hasChanged, this, &GateLibraryWizard::handleWasEdited);
76  connect(boolPage, &BoolWizardPage::hasChanged, this, &GateLibraryWizard::handleWasEdited);
77  connect(latchPage, &LatchWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
78  connect(lutPage, &LUTWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
79  connect(initPage, &InitWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
80  connect(ramPage, &RAMWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
81  connect(ramportPage, &RAMPortWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
82  connect(statePage, &StateWizardPage::completeChanged, this, &GateLibraryWizard::handleWasEdited);
83  }
84 
86  {
87  //Convert QStringList to std::set
88  std::set<GateTypeProperty> properties_set;
89  for(GateTypeProperty prop : generalInfoPage->getProperties())
90  properties_set.insert(prop);
91 
92  if(mGateType)
93  {
94  mGateType = mGateLibrary->replace_gate_type(mGateType->get_id(), generalInfoPage->getName().toStdString(), properties_set, setComponents());
95  //Set pingroups and pins
96  for(PinItem* pingroup : getPingroups())
97  {
98  std::vector<GatePin*> gatepins;
99  for (auto it : pingroup->getChildren()) {
100  PinItem* pin = static_cast<PinItem*>(it);
102  {
103  auto res = mGateType->create_pin(pin->getName().toStdString(), pin->getDirection(), pin->getPinType());
104  if(res.is_ok()) gatepins.push_back(res.get());
105  }
106  }
107  if(pingroup->getItemType() != PinItem::TreeItemType::GroupCreator)
108  mGateType->create_pin_group(pingroup->getName().toStdString(), gatepins, pingroup->getDirection(), pingroup->getPinType());
109  }
110 
111  //TODO: Set boolean functions without adding the same double
112  //also: boolean functions may be removed
113  mGateType->add_boolean_functions(boolPage->getBoolFunctions());
114  }
115  else
116  {
117  //Set name, properties and the parent component
118  mNewGateType = mGateLibrary->create_gate_type(generalInfoPage->getName().toStdString(), properties_set, setComponents());
119  //Set pingroups and pins
120  for(PinItem* pingroup : getPingroups())
121  {
122  std::vector<GatePin*> gatepins;
123  for (auto it : pingroup->getChildren()) {
124  PinItem* pin = static_cast<PinItem*>(it);
126  {
127  auto res = mNewGateType->create_pin(pin->getName().toStdString(), pin->getDirection(), pin->getPinType());
128  if(res.is_ok()) gatepins.push_back(res.get());
129  }
130  }
131  if(pingroup->getItemType() != PinItem::TreeItemType::GroupCreator)
132  mNewGateType->create_pin_group(pingroup->getName().toStdString(), gatepins, pingroup->getDirection(), pingroup->getPinType());
133  }
134 
135  //Set boolean functions
136  mNewGateType->add_boolean_functions(boolPage->getBoolFunctions());
137  }
138  this->close();
139 
140  if (mWasEdited) Q_EMIT triggerUnsavedChanges();
142  }
143 
144  void GateLibraryWizard::handleWasEdited()
145  {
146  mWasEdited = true;
147  setWindowTitle(mTitle+" *");
148  }
149 
151  return mNewGateType;
152  }
153 
155  {
156  return mPinModel->getPinGroups();
157  }
158 
159  std::unique_ptr<GateTypeComponent> GateLibraryWizard::setComponents()
160  {
161  std::unique_ptr<GateTypeComponent> parentComponent;
162  for(GateTypeProperty prop : generalInfoPage->getProperties())
163  {
164  //Set components
165  if(prop == GateTypeProperty::c_lut)
166  {
167  std::vector<std::string> identifiers;
168  for (QString id : initPage->mIdentifiers->toPlainText().split('\n', SKIP_EMPTY_PARTS) ) {
169  identifiers.push_back(id.toStdString());
170  }
171  std::unique_ptr<GateTypeComponent> init_component = GateTypeComponent::create_init_component(initPage->mCategory->text().toStdString(), identifiers);
172  parentComponent = GateTypeComponent::create_lut_component(std::move(init_component), lutPage->mAscending->isChecked());
173  }
174  else if(prop == GateTypeProperty::ff)
175  {
176  std::vector<std::string> identifiers;
177  for (QString id : initPage->mIdentifiers->toPlainText().split('\n', SKIP_EMPTY_PARTS) ) {
178  identifiers.push_back(id.toStdString());
179  }
180  std::unique_ptr<GateTypeComponent> init_component = GateTypeComponent::create_init_component(initPage->mCategory->text().toStdString(), identifiers);
181  std::unique_ptr<GateTypeComponent> state_component = GateTypeComponent::create_state_component(std::move(init_component),
182  statePage->mStateIdentifier->text().toStdString(),
183  statePage->mNegStateIdentifier->text().toStdString());
184  BooleanFunction next_state_bf;
185  BooleanFunction clock_bf;
186 
187  auto next_state_res = BooleanFunction::from_string(ffPage->mNextState->text().toStdString());
188  auto clock_bf_res = BooleanFunction::from_string(ffPage->mClock->text().toStdString());
189 
190  if(next_state_res.is_ok()) next_state_bf = next_state_res.get();
191  if(clock_bf_res.is_ok()) clock_bf = clock_bf_res.get();
192 
193  std::unique_ptr<GateTypeComponent> component = GateTypeComponent::create_ff_component(std::move(state_component),
194  next_state_bf,
195  clock_bf);
196  FFComponent* ff_component = component->convert_to<FFComponent>();
197 
198  BooleanFunction async_reset;
199  auto async_reset_res = BooleanFunction::from_string(ffPage->mAReset->text().toStdString());
200  if(async_reset_res.is_ok()) async_reset = async_reset_res.get();
201  ff_component->set_async_reset_function(async_reset);
202 
203  BooleanFunction async_set;
204  auto async_set_res = BooleanFunction::from_string(ffPage->mASet->text().toStdString());
205  if(async_set_res.is_ok()) async_set = async_set_res.get();
206  ff_component->set_async_set_function(async_set);
207 
208  const auto behav_state = enum_from_string<AsyncSetResetBehavior>(ffPage->mIntState->text().toStdString(), AsyncSetResetBehavior::undef);
209  const auto behav_neg_state = enum_from_string<AsyncSetResetBehavior>(ffPage->mNegIntState->text().toStdString(), AsyncSetResetBehavior::undef);
210  ff_component->set_async_set_reset_behavior(behav_state, behav_neg_state);
211  parentComponent = std::move(component);
212  }
213  else if(prop == GateTypeProperty::latch)
214  {
215  std::unique_ptr<GateTypeComponent> state_component = GateTypeComponent::create_state_component(nullptr,
216  statePage->mStateIdentifier->text().toStdString(),
217  statePage->mNegStateIdentifier->text().toStdString());
218  std::unique_ptr<GateTypeComponent> component = GateTypeComponent::create_latch_component(std::move(state_component));
219  LatchComponent* latch_component = component->convert_to<LatchComponent>();
220 
221  auto data_in_res = BooleanFunction::from_string(latchPage->mDataIn->text().toStdString());
222  auto enable_res = BooleanFunction::from_string(latchPage->mEnableOn->text().toStdString());
223 
224  if(data_in_res.is_ok()) latch_component->set_data_in_function(data_in_res.get());
225  if(enable_res.is_ok()) latch_component->set_enable_function(enable_res.get());
226 
227  BooleanFunction async_reset;
228  auto async_reset_res = BooleanFunction::from_string(latchPage->mAReset->text().toStdString());
229  if(async_reset_res.is_ok()) async_reset = async_reset_res.get();
230  latch_component->set_async_reset_function(async_reset);
231 
232  BooleanFunction async_set;
233  auto async_set_res = BooleanFunction::from_string(latchPage->mASet->text().toStdString());
234  if(async_set_res.is_ok()) async_set = async_set_res.get();
235  latch_component->set_async_set_function(async_set);
236 
237  const auto behav_state = enum_from_string<AsyncSetResetBehavior>(latchPage->mIntState->text().toStdString(), AsyncSetResetBehavior::undef);
238  const auto behav_neg_state = enum_from_string<AsyncSetResetBehavior>(latchPage->mNegIntState->text().toStdString(), AsyncSetResetBehavior::undef);
239  latch_component->set_async_set_reset_behavior(behav_state, behav_neg_state);
240 
241  parentComponent = std::move(component);
242  }
243  else if(prop == GateTypeProperty::ram)
244  {
245  std::unique_ptr<GateTypeComponent> sub_component = nullptr;
246  std::vector<std::string> identifiers;
247  for (QString id : initPage->mIdentifiers->toPlainText().split('\n', SKIP_EMPTY_PARTS) )
248  identifiers.push_back(id.toStdString());
249  sub_component = GateTypeComponent::create_init_component(initPage->mCategory->text().toStdString(), identifiers);
250 
251  for (RAMPortWizardPage::RAMPort rpEdit : ramportPage->getRamPorts()) {
252  BooleanFunction clocked_on_bf;
253  auto clocked_on_res = BooleanFunction::from_string(rpEdit.clockFunction->text().toStdString());
254  if(clocked_on_res.is_ok()) clocked_on_bf = clocked_on_res.get();
255 
256  BooleanFunction enabled_on_bf;
257  auto enabled_on_res = BooleanFunction::from_string(rpEdit.enableFunciton->text().toStdString());
258  if(enabled_on_res.is_ok()) enabled_on_bf = enabled_on_res.get();
259 
261  std::move(sub_component),
262  rpEdit.dataGroup->text().toStdString(),
263  rpEdit.addressGroup->text().toStdString(),
264  clocked_on_bf,
265  enabled_on_bf,
266  rpEdit.isWritePort->isChecked());
267  }
268  parentComponent = GateTypeComponent::create_ram_component(std::move(sub_component), ramPage->mBitSize->text().toInt());
269  }
270  }
271  return std::move(parentComponent);
272  }
273 
275  {
276  const QList<GateTypeProperty> properties = generalInfoPage->getProperties();
277 
278  switch(currentId()){
279  case GeneralInfo:
280  return Pin;
281  case Pin:
282  if(properties.contains(GateTypeProperty::ff) || properties.contains(GateTypeProperty::latch)) return State;
283  else if(properties.contains(GateTypeProperty::c_lut)) return LUT;
284  else if(properties.contains(GateTypeProperty::ram)) return RAM;
285  return BoolFunc;
286  case State:
287  if(properties.contains(GateTypeProperty::ff)) return FlipFlop;
288  else if (properties.contains(GateTypeProperty::latch)) return Latch;
289  else if (properties.contains(GateTypeProperty::c_lut)) return LUT;
290  else if (properties.contains(GateTypeProperty::ram)) return Init;
291  return BoolFunc;
292  case FlipFlop:
293  if(properties.contains(GateTypeProperty::latch)) return Latch;
294  else if(properties.contains(GateTypeProperty::c_lut)) return LUT;
295  else if(properties.contains(GateTypeProperty::ram)) return RAM;
296  return Init;
297  case Latch:
298  if(properties.contains(GateTypeProperty::c_lut)) return LUT;
299  else if(properties.contains(GateTypeProperty::ram)) return RAM;
300  return Init;
301  case LUT:
302  if(properties.contains(GateTypeProperty::ram)) return RAM;
303  return Init;
304  case RAM:
305  return RAMPort;
306  case RAMPort:
307  if(properties.contains(GateTypeProperty::ff) || properties.contains(GateTypeProperty::latch)) return State;
308  return Init;
309  case Init:
310  if(properties.contains(GateTypeProperty::c_lut)) return -1;
311  return BoolFunc;
312  case BoolFunc:
313  default:
314  return -1;
315  }
316  }
317 }
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)
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)
int nextId() const override
QList< PinItem * > getPingroups()
std::unique_ptr< GateTypeComponent > setComponents()
GateLibraryWizard(GateLibrary *gateLibrary, GateType *gateType=nullptr, QWidget *parent=nullptr)
friend class GeneralInfoWizardPage
static std::unique_ptr< GateTypeComponent > create_state_component(std::unique_ptr< GateTypeComponent > component, const std::string &state_identifier, const std::string &neg_state_identifier)
static std::unique_ptr< GateTypeComponent > create_lut_component(std::unique_ptr< GateTypeComponent > component, bool init_ascending)
static std::unique_ptr< GateTypeComponent > create_init_component(const std::string &init_category, const std::vector< std::string > &init_identifiers)
static std::unique_ptr< GateTypeComponent > create_latch_component(std::unique_ptr< GateTypeComponent > component)
static std::unique_ptr< GateTypeComponent > create_ram_component(std::unique_ptr< GateTypeComponent > component, const u32 bit_size)
static std::unique_ptr< GateTypeComponent > create_ff_component(std::unique_ptr< GateTypeComponent > component, const BooleanFunction &next_state_bf, const BooleanFunction &clock_bf)
static std::unique_ptr< GateTypeComponent > create_ram_port_component(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)
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)
void setData(GateType *gate)
void setData(GateType *gate)
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)
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 * > getPinGroups() const
Definition: pin_model.cpp:632
QList< RAMPort > getRamPorts()
void setData(GateType *gate)
void setData(GateType *gate)
void setData(GateType *gate)
#define SKIP_EMPTY_PARTS
FileStatusManager * gFileStatusManager
Definition: plugin_gui.cpp:84
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()