HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
solve_fsm_interaction.cpp
Go to the documentation of this file.
2 #include "gui/gui_globals.h"
3 #include "gui/gui_api/gui_api.h"
4 #include <QRegularExpression>
5 #include <QGraphicsView>>
6 #include "QGVCore/QGVEdge.h"
7 #include "QGVCore/QGVNode.h"
8 #include <QPixmap>
9 #include <QIcon>
12 
13 namespace hal {
14  SolveFsmInteractionRegistration SolveFsmInteractionRegistration::sRegistration;
15 
16  QGVInteraction* constructSolveFsmInteraction(QGVScene* parent)
17  {
18  return new SolveFsmInteraction(parent);
19  }
20 
22  {
23  QGVInteraction::registerConstructorForPlugin("solve_fsm", constructSolveFsmInteraction);
24  }
25 
27  : QGVInteraction(parent), mScene(parent)
28  {
29  connect(gSelectionRelay, &SelectionRelay::selectionChanged, this, &SolveFsmInteraction::handleHALSelectionChanged);
30  connect(parent, &QGraphicsScene::selectionChanged, this, &SolveFsmInteraction::handleQGVSelectionChanged);
31  connect(parent, &QGVScene::edgeContextMenu, this, &SolveFsmInteraction::handleEdgeContextMenu);
32  connect(parent, &QGraphicsScene::changed, this, &SolveFsmInteraction::handleSceneChanged);
33  }
34 
36  {;}
37 
38 
39  void SolveFsmInteraction::handleSceneChanged(const QList<QRectF>& changedArea)
40  {
41  Q_UNUSED(changedArea);
42 
43  if (!mItemArea.isNull())
44  {
45  resetEdgeHighlight();
46 
47  for (QGraphicsView* view : mScene->views())
48  view->ensureVisible(mItemArea);
49  mItemArea = QRectF(); // call ensure visible only once
50  }
51  }
52 
54  {
55  if (mItemArea.isNull())
56  mItemArea = edge->boundingRect();
57  else
58  mItemArea = mItemArea.united(edge->boundingRect());
59  QRegularExpression reNet("net_(\\d+)\\b");
60  QRegularExpressionMatchIterator itNet = reNet.globalMatch(edge->label());
61  while (itNet.hasNext())
62  {
63  QRegularExpressionMatch mNet = itNet.next();
64  bool ok = false;
65  u32 netId = mNet.captured(1).toUInt(&ok);
66  if (!ok || !netId) continue;
67  Net* n = gNetlist->get_net_by_id(netId);
68  if (!n) continue;
69  mNetHash.insert(netId, edge);
70  }
71  }
72 
74  {
75  if (mItemArea.isNull())
76  mItemArea = node->boundingRect();
77  else
78  mItemArea = mItemArea.united(node->boundingRect());
79  }
80 
81  QMap<Net*, int> SolveFsmInteraction::transitionValues(QGVEdge* edge) const
82  {
83  if (!edge || edge->label().isNull())
84  return QMap<Net*,int>();
85  Result<BooleanFunction> resBf = BooleanFunction::from_string(edge->label().toStdString());
86  if (!resBf.is_ok())
87  return QMap<Net*,int>();
89  if (!resEq.is_ok())
90  return QMap<Net*,int>();
91  auto config = hal::SMT::QueryConfig();
92  config.with_model_generation();
93  auto resSv = SMT::Solver({SMT::Constraint(resEq.get())}).query(config);
94  if (!resSv.is_ok())
95  return QMap<Net*,int>();
96  auto solverResult = resSv.get();
97  if (!solverResult.model.has_value())
98  return QMap<Net*,int>();
99  auto model = solverResult.model.value();
100  QMap<Net*,int> retval;
101  for (auto jt = model.model.begin(); jt != model.model.end(); ++jt)
102  {
103  QString netName = QString::fromStdString(jt->first);
104  if (!netName.startsWith("net_")) continue;
105  netName.remove(0,4);
106  bool ok = false;
107  u32 netId = netName.toUInt(&ok);
108  if (!ok) continue;
109  Net* n = gNetlist->get_net_by_id(netId);
110  if (!n) continue;
111  retval[n] = std::get<0>(jt->second);
112  }
113  return retval;
114  }
115 
116  void SolveFsmInteraction::handleEdgeContextMenu(QGVEdge* edge)
117  {
118  resetEdgeHighlight();
119 
120  QPixmap pixOne(32,32);
121  pixOne.fill(QColor::fromRgb(255,0,0));
122  QPixmap pixZero(32,32);
123  pixZero.fill(QColor::fromRgb(0,170,255));
124  QIcon icons[2] = { QIcon(pixZero), QIcon(pixOne) } ;
125  mDisableHandler = true;
126  QMenu menu;
127  QAction* act = menu.addAction("Nets for transition");
128  act->setDisabled(true);
129  menu.addSeparator();
130 
131  QMap<Net*, int> tvals = SolveFsmInteraction::transitionValues(edge);
132  for (auto jt = tvals.begin(); jt != tvals.end(); ++jt)
133  {
134  Net* n = jt.key();
135  act = menu.addAction(icons[jt.value()], QString(" %1 [ID=%2]").arg(n->get_name().c_str()).arg(n->get_id()));
136  connect(act, &QAction::triggered, this, [n](){gGuiApi->selectNet(n,true,true);});
137  }
138  menu.exec(QCursor::pos());
139  mDisableHandler = false;
140  }
141 
142  void SolveFsmInteraction::handleQGVSelectionChanged()
143  {
144  if (mDisableHandler) return;
145  mDisableHandler = true;
146  resetEdgeHighlight();
147 
149  QHash<Net*,int> netValueHash;
150  for (Net* n : gNetlist->get_nets())
151  netValueHash[n] = 0;
152  bool hasTransitions = false;
153 
154  for (QGraphicsItem* it : mScene->selectedItems())
155  {
156  QGVEdge* edge = dynamic_cast<QGVEdge*>(it);
157  QMap<Net*, int> tvals = SolveFsmInteraction::transitionValues(edge);
158  for (auto jt = tvals.begin(); jt != tvals.end(); ++jt)
159  {
160  netValueHash[jt.key()] = jt.value() + 1;
161  hasTransitions = true;
162  }
163 
164  }
165 
166  GroupingTableModel* gtm = gContentManager->getGroupingManagerWidget()->getModel();
167  const char* color[] = {"#707071", "#102080", "#802010" };
168  static const char* grpNames[3] = {"x state", "0 state", "1 state"};
169  Grouping* grp[3];
170  for (int i=0; i<3; i++)
171  {
172  grp[i] = gtm->groupingByName(grpNames[i]);
173  if (grp[i])
174  {
175  if (!hasTransitions)
176  gNetlist->delete_grouping(grp[i]);
177  }
178  else
179  {
180  if (hasTransitions)
181  {
182  grp[i] = gNetlist->create_grouping(grpNames[i]);
183  gtm->recolorGrouping(grp[i]->get_id(),QColor(color[i]));
184  }
185  }
186  }
187 
188  if (hasTransitions)
189  {
190  for (auto it = netValueHash.constBegin(); it != netValueHash.constEnd(); ++it)
191  {
192  Q_ASSERT(it.value() >= 0 && it.value() <= 2);
193  grp[it.value()]->assign_net(const_cast<Net*>(it.key()),true);
194  }
195  }
196  mDisableHandler = false;
197  }
198 
199  void SolveFsmInteraction::resetEdgeHighlight()
200  {
201  for (QGVEdge* edge : mNetHash.values())
202  edge->setHightlight(QString());
203  }
204 
205  void SolveFsmInteraction::handleHALSelectionChanged(void* sender)
206  {
207  if (mDisableHandler) return;
208  Q_UNUSED(sender);
209  if (!mScene) return;
210  resetEdgeHighlight();
211 
212  mDisableHandler = true;
213  mScene->clearSelection();
214  bool first = true;
215  for (u32 netId : gSelectionRelay->selectedNetsList())
216  {
217  for (QGVEdge * edge : mNetHash.values(netId))
218  {
219  edge->setHightlight(QString("net_%1").arg(netId));
220  if (first)
221  for (QGraphicsView* gv : mScene->views())
222  gv->ensureVisible(edge);
223  first = false;
224  }
225  if (!first) break;
226  }
227  mDisableHandler = false;
228  }
229 }
static Result< BooleanFunction > Eq(BooleanFunction &&p0, BooleanFunction &&p1, u16 size)
static Result< BooleanFunction > from_string(const std::string &expression)
static BooleanFunction Const(const BooleanFunction::Value &value)
GroupingManagerWidget * getGroupingManagerWidget()
GroupingTableModel * getModel() const
Grouping * groupingByName(const QString &name) const
void selectNet(u32 netId, bool clear_current_selection=true, bool navigate_to_selection=true)
Definition: gui_api.cpp:149
Definition: net.h:58
Grouping * create_grouping(const u32 grouping_id, const std::string &name="")
Definition: netlist.cpp:671
bool delete_grouping(Grouping *grouping)
Definition: netlist.cpp:681
Net * get_net_by_id(u32 net_id) const
Definition: netlist.cpp:353
const std::vector< Net * > & get_nets() const
Definition: netlist.cpp:364
bool is_ok() const
Definition: result.h:143
const T & get() const
Definition: result.h:166
void selectionChanged(void *sender)
QList< u32 > selectedNetsList() const
void registerNode(QGVNode *node) override
SolveFsmInteraction(QGVScene *parent)
void registerEdge(QGVEdge *edge) override
uint32_t u32
Definition: defines.h:41
Definition: defines.h:45
ContentManager * gContentManager
Definition: plugin_gui.cpp:78
QGVInteraction * constructSolveFsmInteraction(QGVScene *parent)
SelectionRelay * gSelectionRelay
Definition: plugin_gui.cpp:83
Netlist * gNetlist
Definition: gui_globals.h:69
GuiApi * gGuiApi
Definition: plugin_gui.cpp:86
void setDisabled(bool b)
void triggered(bool checked)
QColor fromRgb(QRgb rgb)
QPoint pos()
void changed(const QList< QRectF > &region)
void selectionChanged()
QHash::const_iterator constBegin() const const
QHash::const_iterator constEnd() const const
const T value(const Key &key) const const
QMap::iterator begin()
QMap::iterator end()
QAction * addAction(const QString &text)
QAction * addSeparator()
QAction * exec()
typename QHash< Key, T >::iterator insert(const Key &key, const T &value)
QList< T > values(const Key &key) const const
bool isNull() const const
QRectF united(const QRectF &rectangle) const const
QRegularExpressionMatchIterator globalMatch(const QString &subject, int offset, QRegularExpression::MatchType matchType, QRegularExpression::MatchOptions matchOptions) const const
QString captured(int nth) const const
QRegularExpressionMatch next()
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromStdString(const std::string &str)
QString & remove(int position, int n)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
uint toUInt(bool *ok, int base) const const