HAL
wait_to_be_seated.cpp
Go to the documentation of this file.
2 
3 #include "gui/gui_globals.h"
7 
8 #include <QDebug>
9 #include <QMap>
10 #include <QTextStream>
11 
12 namespace hal
13 {
15  {
16  mNode = Node(id, t);
17  }
18 
19  void WaitToBeSeatedEntry::setPredecessorIds(const QMap<u32, WaitToBeSeatedEntry*>& gateMap)
20  {
21  if (getId() <= 0)
22  return;
23 
24  std::vector<Net*> inputNets;
25  if (isModule())
26  {
27  const Module* m = gNetlist->get_module_by_id(getId());
28  if (m)
29  {
30  inputNets = utils::to_vector(m->get_input_nets());
31  }
32  }
33  else
34  {
35  const Gate* g = gNetlist->get_gate_by_id(getId());
36  if (g)
37  inputNets = g->get_fan_in_nets();
38  }
39 
40  for (Net* n : inputNets)
41  {
42  for (const Endpoint* ep : n->get_sources())
43  {
44  Gate* inpGate = ep->get_gate();
45  if (inpGate->is_gnd_gate() || inpGate->is_vcc_gate())
46  break;
47  u32 inpGateId = inpGate->get_id();
48  WaitToBeSeatedEntry* inpEntry = gateMap.value(inpGateId);
49  if (inpEntry)
50  mPredecessorSet.insert(inpEntry);
51  }
52  }
53  }
54 
56  {
57  return QString("%1%2").arg(isModule() ? 'M' : 'G').arg(getId());
58  }
59 
61  {
62  return mNode.isModule() && mNode.id() > 0;
63  }
64 
65  //---------------------------------------------------
67  {
68  return a->getId() < b->getId();
69  }
70 
71  double WaitToBeSeatedEntry::distance(const QPoint& pos, double defaultDistance) const
72  {
73  double retval = 0;
74  int n = mPredecessorSet.size();
75  Q_ASSERT(n > 0);
76 
77  // distance to predecessors already placed
78  for (const QPoint& source : mPredecessorPositions)
79  retval += distance(source, pos);
80 
81  // predecessors not placed yet
82  retval += (n - mPredecessorPositions.size()) * defaultDistance * 4;
83 
84  // average
85  retval /= n;
86 
87  // to break a tie : add module/gate id
88  retval += getId() / 1000000.;
89  return retval;
90  }
91 
93  {
94  int dx = abs(source.x() + 1 - pos.x());
95  int dy = abs(source.y() - pos.y()) - 1;
96  if (dy < 0)
97  {
98  // immediate neighbour
99  if (!dx)
100  return 1;
101  dy = 0;
102  }
103  return 5 + 4 * (dx + dy);
104  }
105 
106  //---------------------------------------------------
107  WaitToBeSeatedList::WaitToBeSeatedList() : mPlacementRound(0), mSideLength(0)
108  {
109  ;
110  }
111 
113  {
114  for (WaitToBeSeatedEntry* wtse : *this)
115  delete wtse;
116  }
117 
119  {
120  for (WaitToBeSeatedEntry* wtse : *this)
121  wtse->setPredecessorIds(mGateMap);
122 
123  for (WaitToBeSeatedEntry* wtse : *this)
124  for (WaitToBeSeatedEntry* wtsePred : wtse->mPredecessorSet)
125  if (wtsePred)
126  wtsePred->mSuccessorSet.insert(wtse);
127 
128  for (WaitToBeSeatedEntry* wtse : *this)
129  if (wtse->mPredecessorSet.isEmpty())
130  {
131  if (wtse->mSuccessorSet.isEmpty())
132  mIsolated.append(wtse);
133  else
134  mStartpoint.append(wtse);
135  }
136 
137  if (mIsolated.size() > 1)
138  std::sort(mIsolated.begin(), mIsolated.end(), compareWaitToBeSeated);
139 
140  if (mStartpoint.size() > 1)
141  std::sort(mStartpoint.begin(), mStartpoint.end(), compareWaitToBeSeated);
142 
143  mSideLength = sqrt(size());
144  }
145 
147  {
148  Q_ASSERT(wtse);
149  append(wtse);
150  if (wtse->isModule())
151  {
152  const Module* m = gNetlist->get_module_by_id(wtse->getId());
153  if (m)
154  {
155  for (const Gate* g : m->get_gates(nullptr, true))
156  if (g)
157  mGateMap.insert(g->get_id(), wtse);
158  }
159  }
160  else
161  mGateMap.insert(wtse->getId(), wtse);
162  }
163 
165  {
166  bool isEdge = pos.x() == 0 || pos.y() == 0;
167  if (!mIsolated.isEmpty() && (isEdge || mWaiting.isEmpty()))
168  {
169  return doPlacement(pos, mIsolated.takeFirst());
170  }
171  if (!mStartpoint.isEmpty() && (isEdge || mWaiting.isEmpty()))
172  {
173  return doPlacement(pos, mStartpoint.takeFirst());
174  }
175 
176  if (mWaiting.isEmpty() && !placementDone())
177  {
178  for (WaitToBeSeatedEntry* wtse : *this)
179  if (!mPlaced.contains(wtse))
180  {
181  mWaiting.insert(wtse, mPlacementRound);
182  break;
183  }
184  }
185 
186  if (!mWaiting.isEmpty())
187  {
188  double minDistance = 0;
189  QMap<WaitToBeSeatedEntry*, int>::iterator jt = mWaiting.end();
190  for (QMap<WaitToBeSeatedEntry*, int>::iterator it = mWaiting.begin(); it != mWaiting.end(); ++it)
191  {
192  double distance = it.key()->distance(pos, mSideLength) - 0.5 * (mPlacementRound - it.value());
193  if (jt == mWaiting.end() || distance < minDistance)
194  {
195  minDistance = distance;
196  jt = it;
197  }
198  }
199  Q_ASSERT(jt != mWaiting.end());
200  WaitToBeSeatedEntry* closest = jt.key();
201  mWaiting.erase(jt);
202  return doPlacement(pos, closest);
203  }
204 
205  return nullptr;
206  }
207 
209  {
210  assert(!mPlaced.contains(wtse));
211  ++mPlacementRound;
212  mPlaced.insert(wtse);
213  for (WaitToBeSeatedEntry* wtseSucc : wtse->mSuccessorSet)
214  {
215  wtseSucc->mPredecessorPositions.append(pos);
216  if (!mWaiting.contains(wtseSucc) && !mPlaced.contains(wtseSucc))
217  mWaiting.insert(wtseSucc, mPlacementRound);
218  }
219  return wtse;
220  }
221 
223  {
224  QTextStream xout(stdout, QIODevice::WriteOnly);
225  xout << "WaitToBeSeatedList\n";
226  for (WaitToBeSeatedEntry* wtse : *this)
227  {
228  xout.setFieldWidth(4);
229  xout << wtse->getId();
230  xout << (wtse->isModule() ? "MOD" : "GAT");
231  xout << "<<<";
232  for (WaitToBeSeatedEntry* wtsePred : wtse->mPredecessorSet)
233  {
234  xout << wtsePred->tagName();
235  }
236  xout << ">>>";
237  for (WaitToBeSeatedEntry* wtseSucc : wtse->mSuccessorSet)
238  {
239  xout << wtseSucc->tagName();
240  }
241  xout.setFieldWidth(0);
242  xout << "\n";
243  }
244  xout << "------------------------\n";
245  }
246 
247 } // namespace hal
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation source
Definition: gate.h:58
const std::vector< Gate * > & get_gates() const
Definition: module.cpp:391
const std::unordered_set< Net * > & get_input_nets() const
Definition: module.cpp:540
Gate * get_gate_by_id(const u32 gate_id) const
Definition: netlist.cpp:193
Module * get_module_by_id(u32 module_id) const
Definition: netlist.cpp:613
The Node class object represents a module or a gate.
Definition: gui_def.h:61
bool isModule() const
isModule test wheter node is a module
Definition: gui_def.h:95
u32 id() const
id getter for ID information
Definition: gui_def.h:77
bool isModule() const
QString tagName() const
double distance(const QPoint &pos, double defaultDistance) const
u32 getId() const
WaitToBeSeatedEntry(Node::NodeType t=Node::Module, u32 id=0)
void add(WaitToBeSeatedEntry *wtse)
const WaitToBeSeatedEntry * doPlacement(const QPoint &pos, WaitToBeSeatedEntry *wtse)
const WaitToBeSeatedEntry * nextPlacement(const QPoint &pos)
CORE_API std::vector< T > to_vector(const Container< T, Args... > &container)
Definition: utils.h:513
bool compareWaitToBeSeated(const WaitToBeSeatedEntry *a, const WaitToBeSeatedEntry *b)
Netlist * gNetlist
Definition: plugin_gui.cpp:80
n
Definition: test.py:6
quint32 u32
void append(const T &value)
QList::iterator begin()
QList::iterator end()
bool isEmpty() const const
int size() const const
T takeFirst()
const Key & key() const const
const T value(const Key &key, const T &defaultValue) const const
int x() const const
int y() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
void setFieldWidth(int width)