HAL  v4.5.0-254-g8f9f6a423
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
lut_wizardpage.cpp
Go to the documentation of this file.
5 
6 #include <QComboBox>
7 #include <QHeaderView>
8 #include <QSpinBox>
9 
10 namespace hal
11 {
13  {
14  setTitle("LUT Init");
15  setSubTitle("Enter parameters for LUT component");
16  mLayout = new QGridLayout(this);
17 
18  mLabAscending = new QLabel("Bit order ascending: ");
19  mAscending = new QCheckBox(this);
20  mLayout->addWidget(mLabAscending, 0, 0);
21  mLayout->addWidget(mAscending, 0, 1);
22 
23  mPinConfigTable = new QTableWidget(0, 4, this);
24  mPinConfigTable->setHorizontalHeaderLabels({"Output Pin", "Init Identifier", "Bit Offset", "Bit Count"});
31  mLayout->addWidget(mPinConfigTable, 1, 0, 1, 2);
32 
33  QWidget* btnWidget = new QWidget(this);
34  QHBoxLayout* btnLayout = new QHBoxLayout(btnWidget);
35  btnLayout->setContentsMargins(0, 0, 0, 0);
36  btnLayout->addStretch();
37  mLayout->addWidget(btnWidget, 2, 0, 1, 2);
38 
39  setLayout(mLayout);
40 
43  }
44 
46  {
47  mSavedConfigs.clear();
48 
49  if (gate == nullptr || !gate->has_component_of_type(GateTypeComponent::ComponentType::lut))
50  return;
51 
52  auto* lutc = gate->get_component_as<LUTComponent>([](const GateTypeComponent* c) { return LUTComponent::is_class_of(c); });
53  if (lutc == nullptr)
54  return;
55 
56  const auto& configs = lutc->get_output_pin_configs();
57  bool first_ascending = false;
58  if (!configs.empty())
59  first_ascending = configs.begin()->second.is_ascending;
60  mAscending->setChecked(first_ascending);
61 
62  for (const auto& [pin, cfg] : configs)
63  mSavedConfigs.push_back({pin, cfg.init_identifier, cfg.bit_offset, cfg.bit_count});
64  }
65 
67  {
68  const QStringList pins = getLutPinsFromWizard();
69 
70  auto* wiz = static_cast<GateLibraryWizard*>(wizard());
71  int n = wiz ? wiz->mPinModel->getInputPins().size() : 0;
72  if (n > 30) n = 30;
73  const u32 maxBitCount = 1u << n;
74 
75  mPinConfigTable->setRowCount(0);
76  for (const QString& pin : pins)
77  {
78  const std::string pinName = pin.toStdString();
79 
80  // prefill from an existing configuration if this pin already has one
81  const SavedConfig* saved = nullptr;
82  for (const auto& cfg : mSavedConfigs)
83  {
84  if (cfg.pinName == pinName)
85  {
86  saved = &cfg;
87  break;
88  }
89  }
90 
91  if (saved != nullptr)
92  addTableRow(pin, QString::fromStdString(saved->initIdentifier), saved->bitOffset, saved->bitCount, maxBitCount);
93  else
94  addTableRow(pin, "INIT", 0, 1, maxBitCount);
95  }
96  }
97 
98  QStringList LUTWizardPage::getLutPinsFromWizard() const
99  {
100  auto* wiz = static_cast<GateLibraryWizard*>(wizard());
101  if (!wiz) return {};
102 
103  QStringList result;
104  for (PinItem* group : wiz->getPingroups())
105  {
106  for (auto* child : group->getChildren())
107  {
108  auto* pin = static_cast<PinItem*>(child);
109  if (pin->getItemType() == PinItem::TreeItemType::Pin &&
110  pin->getPinType() == PinType::lut)
111  result << pin->getName();
112  }
113  }
114  return result;
115  }
116 
117  void LUTWizardPage::addTableRow(const QString& pinName, const QString& initId, u32 bitOffset, u32 bitCount, u32 maxBitCount)
118  {
119  int row = mPinConfigTable->rowCount();
120  mPinConfigTable->insertRow(row);
121 
122  auto* pinItem = new QTableWidgetItem(pinName);
123  pinItem->setFlags(pinItem->flags() & ~Qt::ItemIsEditable);
124  mPinConfigTable->setItem(row, 0, pinItem);
125 
126  mPinConfigTable->setItem(row, 1, new QTableWidgetItem(initId));
127 
128  auto* offsetSpin = new QSpinBox(mPinConfigTable);
129  offsetSpin->setRange(0, 1 << 20);
130  offsetSpin->setValue(static_cast<int>(bitOffset));
131  mPinConfigTable->setCellWidget(row, 2, offsetSpin);
132 
133  auto* countCombo = new QComboBox(mPinConfigTable);
134  for (u32 count = 1; count <= maxBitCount; count <<= 1)
135  countCombo->addItem(QString::number(count), count);
136  countCombo->setCurrentIndex(countCombo->findData(bitCount));
137  mPinConfigTable->setCellWidget(row, 3, countCombo);
138  connect(countCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LUTWizardPage::completeChanged);
139  }
140 
142  {
144  for (int r = 0; r < mPinConfigTable->rowCount(); ++r)
145  {
146  auto* pinItem = mPinConfigTable->item(r, 0);
147  auto* offsetSpin = qobject_cast<QSpinBox*>(mPinConfigTable->cellWidget(r, 2));
148  auto* countCombo = qobject_cast<QComboBox*>(mPinConfigTable->cellWidget(r, 3));
149 
150  const QString pin = pinItem ? pinItem->text() : QString();
151  if (pin.isEmpty()) continue;
152 
153  auto* idItem = mPinConfigTable->item(r, 1);
154  const QString id = idItem ? idItem->text() : QString();
155 
156  result.push_back({pin, id,
157  static_cast<u32>(offsetSpin ? offsetSpin->value() : 0),
158  countCombo ? countCombo->currentData().toUInt() : 0});
159  }
160  return result;
161  }
162 
164  {
165  for (int row = 0; row < mPinConfigTable->rowCount(); ++row)
166  {
167  auto* pinInitIdentifier = mPinConfigTable->item(row, 1);
168  if (pinInitIdentifier == nullptr || pinInitIdentifier->text().trimmed().isEmpty()) return false;
169 
170  auto* countCombo = qobject_cast<QComboBox*>(mPinConfigTable->cellWidget(row, 3));
171  const u32 count = countCombo ? countCombo->currentData().toUInt() : 0;
172  if (count == 0 || count & (count - 1)) return false; // ensure bit count is non-zero power of two
173  }
174 
175  return true;
176  }
177 }
bool has_component_of_type(const GateTypeComponent::ComponentType type) const
Definition: gate_type.cpp:54
T * get_component_as(const std::function< bool(const GateTypeComponent *)> &filter=nullptr) const
Definition: gate_type.h:89
const std::unordered_map< std::string, LUTOutputConfig > & get_output_pin_configs() const
static bool is_class_of(const GateTypeComponent *component)
void initializePage() override
void setData(GateType *gate)
QVector< OutputPinEntry > getOutputPinConfigs() const
LUTWizardPage(QWidget *parent=nullptr)
bool isComplete() const override
QList< PinItem * > getInputPins()
Definition: pin_model.cpp:733
uint32_t u32
Definition: defines.h:41
Definition: defines.h:45
std::vector< PinInformation > pins
i32 id
void setChecked(bool)
void setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior)
void setSelectionMode(QAbstractItemView::SelectionMode mode)
void addStretch(int stretch)
void stateChanged(int state)
void currentIndexChanged(int index)
void addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment)
void setSectionResizeMode(QHeaderView::ResizeMode mode)
void setContentsMargins(int left, int top, int right, int bottom)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString fromStdString(const std::string &str)
bool isEmpty() const const
QString number(int n, int base)
ItemIsEditable
QHeaderView * horizontalHeader() const const
QWidget * cellWidget(int row, int column) const const
void insertRow(int row)
QTableWidgetItem * item(int row, int column) const const
void itemChanged(QTableWidgetItem *item)
void setCellWidget(int row, int column, QWidget *widget)
void setHorizontalHeaderLabels(const QStringList &labels)
void setItem(int row, int column, QTableWidgetItem *item)
void setRowCount(int rows)
void push_back(const T &value)
QWidget(QWidget *parent, Qt::WindowFlags f)
void setLayout(QLayout *layout)
void completeChanged()
void setSubTitle(const QString &subTitle)
void setTitle(const QString &title)
QWizard * wizard() const const