yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
modtools.h
Go to the documentation of this file.
1 /*
2  * yosys -- Yosys Open SYnthesis Suite
3  *
4  * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  */
19 
20 #ifndef MODTOOLS_H
21 #define MODTOOLS_H
22 
23 #include "kernel/yosys.h"
24 #include "kernel/sigtools.h"
25 #include "kernel/celltypes.h"
26 
28 
29 struct ModIndex : public RTLIL::Monitor
30 {
31  struct PortInfo {
34  int offset;
35 
36  PortInfo(RTLIL::Cell* _c, RTLIL::IdString _p, int _o) : cell(_c), port(_p), offset(_o) { }
37 
38  bool operator<(const PortInfo &other) const {
39  if (cell != other.cell)
40  return cell < other.cell;
41  if (offset != other.offset)
42  return offset < other.offset;
43  return port < other.port;
44  }
45  };
46 
47  struct SigBitInfo
48  {
50  std::set<PortInfo> ports;
51 
52  SigBitInfo() : is_input(false), is_output(false) { }
53  };
54 
57  std::map<RTLIL::SigBit, SigBitInfo> database;
59 
60  void port_add(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig)
61  {
62  for (int i = 0; i < GetSize(sig); i++) {
63  RTLIL::SigBit bit = sigmap(sig[i]);
64  if (bit.wire)
65  database[bit].ports.insert(PortInfo(cell, port, i));
66  }
67  }
68 
69  void port_del(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig)
70  {
71  for (int i = 0; i < GetSize(sig); i++) {
72  RTLIL::SigBit bit = sigmap(sig[i]);
73  if (bit.wire)
74  database[bit].ports.erase(PortInfo(cell, port, i));
75  }
76  }
77 
79  {
80  return database[sigmap(bit)];
81  }
82 
84  {
85  sigmap.clear();
86  sigmap.set(module);
87 
88  database.clear();
89  for (auto wire : module->wires())
90  if (wire->port_input || wire->port_output)
91  for (int i = 0; i < GetSize(wire); i++) {
92  RTLIL::SigBit bit = sigmap(RTLIL::SigBit(wire, i));
93  if (bit.wire && wire->port_input)
94  database[bit].is_input = true;
95  if (bit.wire && wire->port_output)
96  database[bit].is_output = true;
97  }
98  for (auto cell : module->cells())
99  for (auto &conn : cell->connections())
100  port_add(cell, conn.first, conn.second);
101 
102  auto_reload_module = false;
103  }
104 
105  virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE
106  {
107  if (auto_reload_module)
108  reload_module();
109 
110  port_del(cell, port, old_sig);
111  port_add(cell, port, sig);
112  }
113 
114  virtual void notify_connect(RTLIL::Module *mod, const RTLIL::SigSig&)
115  {
116  log_assert(module == mod);
117  auto_reload_module = true;
118  }
119 
120  virtual void notify_connect(RTLIL::Module *mod, const std::vector<RTLIL::SigSig>&)
121  {
122  log_assert(module == mod);
123  auto_reload_module = true;
124  }
125 
126  virtual void notify_blackout(RTLIL::Module *mod)
127  {
128  log_assert(module == mod);
129  auto_reload_module = true;
130  }
131 
133  {
134  auto_reload_module = true;
135  module->monitors.insert(this);
136  }
137 
139  {
140  module->monitors.erase(this);
141  }
142 
144  {
145  if (auto_reload_module)
146  reload_module();
147 
148  auto it = database.find(sigmap(bit));
149  if (it == database.end())
150  return nullptr;
151  else
152  return &it->second;
153  }
154 
156  {
157  const SigBitInfo *info = query(bit);
158  if (info == nullptr)
159  return false;
160  return info->is_input;
161  }
162 
164  {
165  const SigBitInfo *info = query(bit);
166  if (info == nullptr)
167  return false;
168  return info->is_output;
169  }
170 
171  std::set<PortInfo> &query_ports(RTLIL::SigBit bit)
172  {
173  static std::set<PortInfo> empty_result_set;
174  SigBitInfo *info = query(bit);
175  if (info == nullptr)
176  return empty_result_set;
177  return info->ports;
178  }
179 };
180 
181 struct ModWalker
182 {
183  struct PortBit
184  {
187  int offset;
188 
189  bool operator<(const PortBit &other) const {
190  if (cell != other.cell)
191  return cell < other.cell;
192  if (port != other.port)
193  return port < other.port;
194  return offset < other.offset;
195  }
196  };
197 
200 
203 
204  std::map<RTLIL::SigBit, std::set<PortBit>> signal_drivers;
205  std::map<RTLIL::SigBit, std::set<PortBit>> signal_consumers;
206  std::set<RTLIL::SigBit> signal_inputs, signal_outputs;
207 
208  std::map<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_outputs, cell_inputs;
209 
210  void add_wire(RTLIL::Wire *wire)
211  {
212  if (wire->port_input) {
213  std::vector<RTLIL::SigBit> bits = sigmap(wire);
214  for (auto bit : bits)
215  if (bit.wire != NULL)
216  signal_inputs.insert(bit);
217  }
218 
219  if (wire->port_output) {
220  std::vector<RTLIL::SigBit> bits = sigmap(wire);
221  for (auto bit : bits)
222  if (bit.wire != NULL)
223  signal_outputs.insert(bit);
224  }
225  }
226 
227  void add_cell_port(RTLIL::Cell *cell, RTLIL::IdString port, std::vector<RTLIL::SigBit> bits, bool is_output, bool is_input)
228  {
229  for (int i = 0; i < int(bits.size()); i++)
230  if (bits[i].wire != NULL) {
231  PortBit pbit = { cell, port, i };
232  if (is_output) {
233  signal_drivers[bits[i]].insert(pbit);
234  cell_outputs[cell].insert(bits[i]);
235  }
236  if (is_input) {
237  signal_consumers[bits[i]].insert(pbit);
238  cell_inputs[cell].insert(bits[i]);
239  }
240  }
241  }
242 
243  void add_cell(RTLIL::Cell *cell)
244  {
245  if (ct.cell_known(cell->type)) {
246  for (auto &conn : cell->connections())
247  add_cell_port(cell, conn.first, sigmap(conn.second),
248  ct.cell_output(cell->type, conn.first),
249  ct.cell_input(cell->type, conn.first));
250  } else {
251  for (auto &conn : cell->connections())
252  add_cell_port(cell, conn.first, sigmap(conn.second), true, true);
253  }
254  }
255 
257  {
258  }
259 
261  {
262  setup(design, module, filter_ct);
263  }
264 
266  {
267  this->design = design;
268  this->module = module;
269 
270  ct.clear();
271  ct.setup(design);
272  sigmap.set(module);
273 
274  signal_drivers.clear();
275  signal_consumers.clear();
276  signal_inputs.clear();
277  signal_outputs.clear();
278 
279  for (auto &it : module->wires_)
280  add_wire(it.second);
281  for (auto &it : module->cells_)
282  if (filter_ct == NULL || filter_ct->cell_known(it.second->type))
283  add_cell(it.second);
284  }
285 
286  // get_* methods -- single RTLIL::SigBit
287 
288  template<typename T>
289  inline bool get_drivers(std::set<PortBit> &result, RTLIL::SigBit bit) const
290  {
291  bool found = false;
292  if (signal_drivers.count(bit)) {
293  const std::set<PortBit> &r = signal_drivers.at(bit);
294  result.insert(r.begin(), r.end());
295  found = true;
296  }
297  return found;
298  }
299 
300  template<typename T>
301  inline bool get_consumers(std::set<PortBit> &result, RTLIL::SigBit bit) const
302  {
303  bool found = false;
304  if (signal_consumers.count(bit)) {
305  const std::set<PortBit> &r = signal_consumers.at(bit);
306  result.insert(r.begin(), r.end());
307  found = true;
308  }
309  return found;
310  }
311 
312  template<typename T>
313  inline bool get_inputs(std::set<RTLIL::SigBit> &result, RTLIL::SigBit bit) const
314  {
315  bool found = false;
316  if (signal_inputs.count(bit))
317  result.insert(bit), found = true;
318  return found;
319  }
320 
321  template<typename T>
322  inline bool get_outputs(std::set<RTLIL::SigBit> &result, RTLIL::SigBit bit) const
323  {
324  bool found = false;
325  if (signal_outputs.count(bit))
326  result.insert(bit), found = true;
327  return found;
328  }
329 
330  // get_* methods -- container of RTLIL::SigBit's (always by reference)
331 
332  template<typename T>
333  inline bool get_drivers(std::set<PortBit> &result, const T &bits) const
334  {
335  bool found = false;
336  for (RTLIL::SigBit bit : bits)
337  if (signal_drivers.count(bit)) {
338  const std::set<PortBit> &r = signal_drivers.at(bit);
339  result.insert(r.begin(), r.end());
340  found = true;
341  }
342  return found;
343  }
344 
345  template<typename T>
346  inline bool get_consumers(std::set<PortBit> &result, const T &bits) const
347  {
348  bool found = false;
349  for (RTLIL::SigBit bit : bits)
350  if (signal_consumers.count(bit)) {
351  const std::set<PortBit> &r = signal_consumers.at(bit);
352  result.insert(r.begin(), r.end());
353  found = true;
354  }
355  return found;
356  }
357 
358  template<typename T>
359  inline bool get_inputs(std::set<RTLIL::SigBit> &result, const T &bits) const
360  {
361  bool found = false;
362  for (RTLIL::SigBit bit : bits)
363  if (signal_inputs.count(bit))
364  result.insert(bit), found = true;
365  return found;
366  }
367 
368  template<typename T>
369  inline bool get_outputs(std::set<RTLIL::SigBit> &result, const T &bits) const
370  {
371  bool found = false;
372  for (RTLIL::SigBit bit : bits)
373  if (signal_outputs.count(bit))
374  result.insert(bit), found = true;
375  return found;
376  }
377 
378  // get_* methods -- call by RTLIL::SigSpec (always by value)
379 
380  bool get_drivers(std::set<PortBit> &result, RTLIL::SigSpec signal) const
381  {
382  std::vector<RTLIL::SigBit> bits = sigmap(signal);
383  return get_drivers(result, bits);
384  }
385 
386  bool get_consumers(std::set<PortBit> &result, RTLIL::SigSpec signal) const
387  {
388  std::vector<RTLIL::SigBit> bits = sigmap(signal);
389  return get_consumers(result, bits);
390  }
391 
392  bool get_inputs(std::set<RTLIL::SigBit> &result, RTLIL::SigSpec signal) const
393  {
394  std::vector<RTLIL::SigBit> bits = sigmap(signal);
395  return get_inputs(result, bits);
396  }
397 
398  bool get_outputs(std::set<RTLIL::SigBit> &result, RTLIL::SigSpec signal) const
399  {
400  std::vector<RTLIL::SigBit> bits = sigmap(signal);
401  return get_outputs(result, bits);
402  }
403 
404  // has_* methods -- call by reference
405 
406  template<typename T>
407  inline bool has_drivers(const T &sig) const {
408  std::set<PortBit> result;
409  return get_drivers(result, sig);
410  }
411 
412  template<typename T>
413  inline bool has_consumers(const T &sig) const {
414  std::set<PortBit> result;
415  return get_consumers(result, sig);
416  }
417 
418  template<typename T>
419  inline bool has_inputs(const T &sig) const {
420  std::set<RTLIL::SigBit> result;
421  return get_inputs(result, sig);
422  }
423 
424  template<typename T>
425  inline bool has_outputs(const T &sig) const {
426  std::set<RTLIL::SigBit> result;
427  return get_outputs(result, sig);
428  }
429 
430  // has_* methods -- call by value
431 
432  inline bool has_drivers(RTLIL::SigSpec sig) const {
433  std::set<PortBit> result;
434  return get_drivers(result, sig);
435  }
436 
437  inline bool has_consumers(RTLIL::SigSpec sig) const {
438  std::set<PortBit> result;
439  return get_consumers(result, sig);
440  }
441 
442  inline bool has_inputs(RTLIL::SigSpec sig) const {
443  std::set<RTLIL::SigBit> result;
444  return get_inputs(result, sig);
445  }
446 
447  inline bool has_outputs(RTLIL::SigSpec sig) const {
448  std::set<RTLIL::SigBit> result;
449  return get_outputs(result, sig);
450  }
451 };
452 
454 
455 #endif
std::map< RTLIL::SigBit, std::set< PortBit > > signal_consumers
Definition: modtools.h:205
std::map< RTLIL::SigBit, SigBitInfo > database
Definition: modtools.h:57
RTLIL::Wire * wire
Definition: rtlil.h:907
std::map< RTLIL::Cell *, std::set< RTLIL::SigBit > > cell_outputs
Definition: modtools.h:208
bool get_drivers(std::set< PortBit > &result, RTLIL::SigSpec signal) const
Definition: modtools.h:380
bool get_inputs(std::set< RTLIL::SigBit > &result, const T &bits) const
Definition: modtools.h:359
bool auto_reload_module
Definition: modtools.h:58
std::set< RTLIL::SigBit > signal_outputs
Definition: modtools.h:206
void clear()
Definition: celltypes.h:183
~ModIndex()
Definition: modtools.h:138
bool has_inputs(RTLIL::SigSpec sig) const
Definition: modtools.h:442
void add_cell_port(RTLIL::Cell *cell, RTLIL::IdString port, std::vector< RTLIL::SigBit > bits, bool is_output, bool is_input)
Definition: modtools.h:227
bool has_drivers(RTLIL::SigSpec sig) const
Definition: modtools.h:432
std::set< RTLIL::Monitor * > monitors
Definition: rtlil.h:590
bool get_consumers(std::set< PortBit > &result, RTLIL::SigSpec signal) const
Definition: modtools.h:386
#define YS_OVERRIDE
Definition: yosys.h:108
bool get_drivers(std::set< PortBit > &result, const T &bits) const
Definition: modtools.h:333
virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE
Definition: modtools.h:105
ModWalker()
Definition: modtools.h:256
void setup(RTLIL::Design *design=NULL)
Definition: celltypes.h:47
bool has_drivers(const T &sig) const
Definition: modtools.h:407
#define YOSYS_NAMESPACE_END
Definition: yosys.h:100
SigMap sigmap
Definition: modtools.h:202
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
Definition: rtlil.h:595
void clear()
Definition: sigtools.h:263
void port_add(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig)
Definition: modtools.h:60
bool port_input
Definition: rtlil.h:827
RTLIL::ObjRange< RTLIL::Wire * > wires()
Definition: rtlil.h:640
bool has_consumers(RTLIL::SigSpec sig) const
Definition: modtools.h:437
bool get_inputs(std::set< RTLIL::SigBit > &result, RTLIL::SigSpec signal) const
Definition: modtools.h:392
RTLIL::IdString type
Definition: rtlil.h:854
bool has_outputs(RTLIL::SigSpec sig) const
Definition: modtools.h:447
PortInfo(RTLIL::Cell *_c, RTLIL::IdString _p, int _o)
Definition: modtools.h:36
bool has_outputs(const T &sig) const
Definition: modtools.h:425
bool get_drivers(std::set< PortBit > &result, RTLIL::SigBit bit) const
Definition: modtools.h:289
bool get_outputs(std::set< RTLIL::SigBit > &result, RTLIL::SigBit bit) const
Definition: modtools.h:322
const SigBitInfo & info(RTLIL::SigBit bit)
Definition: modtools.h:78
std::set< RTLIL::SigBit > signal_inputs
Definition: modtools.h:206
bool port_output
Definition: rtlil.h:827
bool get_consumers(std::set< PortBit > &result, RTLIL::SigBit bit) const
Definition: modtools.h:301
bool has_inputs(const T &sig) const
Definition: modtools.h:419
SigMap sigmap
Definition: modtools.h:55
void set(RTLIL::Module *module)
Definition: sigtools.h:273
RTLIL::Module * module
Definition: modtools.h:56
bool cell_known(RTLIL::IdString type)
Definition: celltypes.h:188
bool get_consumers(std::set< PortBit > &result, const T &bits) const
Definition: modtools.h:346
bool operator<(const PortBit &other) const
Definition: modtools.h:189
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
Definition: celltypes.h:193
bool query_is_output(RTLIL::SigBit bit)
Definition: modtools.h:163
bool query_is_input(RTLIL::SigBit bit)
Definition: modtools.h:155
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
#define log_assert(_assert_expr_)
Definition: log.h:85
std::set< PortInfo > ports
Definition: modtools.h:50
SigBitInfo * query(RTLIL::SigBit bit)
Definition: modtools.h:143
bool get_outputs(std::set< RTLIL::SigBit > &result, RTLIL::SigSpec signal) const
Definition: modtools.h:398
RTLIL::Design * design
Definition: modtools.h:198
RTLIL::Cell * cell
Definition: modtools.h:185
std::map< RTLIL::Cell *, std::set< RTLIL::SigBit > > cell_inputs
Definition: modtools.h:208
ModIndex(RTLIL::Module *_m)
Definition: modtools.h:132
bool has_consumers(const T &sig) const
Definition: modtools.h:413
void add_wire(RTLIL::Wire *wire)
Definition: modtools.h:210
virtual void notify_connect(RTLIL::Module *mod, const RTLIL::SigSig &)
Definition: modtools.h:114
bool operator<(const PortInfo &other) const
Definition: modtools.h:38
RTLIL::IdString port
Definition: modtools.h:186
virtual void notify_connect(RTLIL::Module *mod, const std::vector< RTLIL::SigSig > &)
Definition: modtools.h:120
RTLIL::ObjRange< RTLIL::Cell * > cells()
Definition: rtlil.h:641
void setup(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct=NULL)
Definition: modtools.h:265
#define NULL
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
Definition: rtlil.h:596
#define YOSYS_NAMESPACE_BEGIN
Definition: yosys.h:99
RTLIL::Module * module
Definition: modtools.h:199
bool get_outputs(std::set< RTLIL::SigBit > &result, const T &bits) const
Definition: modtools.h:369
RTLIL::IdString port
Definition: modtools.h:33
CellTypes ct
Definition: modtools.h:201
RTLIL::Cell * cell
Definition: modtools.h:32
void port_del(RTLIL::Cell *cell, RTLIL::IdString port, const RTLIL::SigSpec &sig)
Definition: modtools.h:69
bool cell_input(RTLIL::IdString type, RTLIL::IdString port)
Definition: celltypes.h:199
std::map< RTLIL::SigBit, std::set< PortBit > > signal_drivers
Definition: modtools.h:204
virtual void notify_blackout(RTLIL::Module *mod)
Definition: modtools.h:126
void reload_module()
Definition: modtools.h:83
std::pair< SigSpec, SigSpec > SigSig
Definition: rtlil.h:71
const std::map< RTLIL::IdString, RTLIL::SigSpec > & connections() const
Definition: rtlil.cc:1814
void add_cell(RTLIL::Cell *cell)
Definition: modtools.h:243
bool get_inputs(std::set< RTLIL::SigBit > &result, RTLIL::SigBit bit) const
Definition: modtools.h:313
std::set< PortInfo > & query_ports(RTLIL::SigBit bit)
Definition: modtools.h:171
ModWalker(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct=NULL)
Definition: modtools.h:260