yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
stubnets.cc
Go to the documentation of this file.
1 // This is free and unencumbered software released into the public domain.
2 //
3 // Anyone is free to copy, modify, publish, use, compile, sell, or
4 // distribute this software, either in source code form or as a compiled
5 // binary, for any purpose, commercial or non-commercial, and by any
6 // means.
7 
8 #include "kernel/yosys.h"
9 #include "kernel/sigtools.h"
10 
11 #include <string>
12 #include <map>
13 #include <set>
14 
17 
18 // this function is called for each module in the design
19 static void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool report_bits)
20 {
21  // use a SigMap to convert nets to a unique representation
22  SigMap sigmap(module);
23 
24  // count how many times a single-bit signal is used
25  std::map<RTLIL::SigBit, int> bit_usage_count;
26 
27  // count ouput lines for this module (needed only for summary output at the end)
28  int line_count = 0;
29 
30  log("Looking for stub wires in module %s:\n", RTLIL::id2cstr(module->name));
31 
32  // For all ports on all cells
33  for (auto &cell_iter : module->cells_)
34  for (auto &conn : cell_iter.second->connections())
35  {
36  // Get the signals on the port
37  // (use sigmap to get a uniqe signal name)
38  RTLIL::SigSpec sig = sigmap(conn.second);
39 
40  // add each bit to bit_usage_count, unless it is a constant
41  for (auto &bit : sig)
42  if (bit.wire != NULL)
43  bit_usage_count[bit]++;
44  }
45 
46  // for each wire in the module
47  for (auto &wire_iter : module->wires_)
48  {
49  RTLIL::Wire *wire = wire_iter.second;
50 
51  // .. but only selected wires
52  if (!design->selected(module, wire))
53  continue;
54 
55  // add +1 usage if this wire actually is a port
56  int usage_offset = wire->port_id > 0 ? 1 : 0;
57 
58  // we will record which bits of the (possibly multi-bit) wire are stub signals
59  std::set<int> stub_bits;
60 
61  // get a signal description for this wire and split it into separate bits
62  RTLIL::SigSpec sig = sigmap(wire);
63 
64  // for each bit (unless it is a constant):
65  // check if it is used at least two times and add to stub_bits otherwise
66  for (int i = 0; i < GetSize(sig); i++)
67  if (sig[i].wire != NULL && (bit_usage_count[sig[i]] + usage_offset) < 2)
68  stub_bits.insert(i);
69 
70  // continue if no stub bits found
71  if (stub_bits.size() == 0)
72  continue;
73 
74  // report stub bits and/or stub wires, don't report single bits
75  // if called with report_bits set to false.
76  if (GetSize(stub_bits) == GetSize(sig)) {
77  log(" found stub wire: %s\n", RTLIL::id2cstr(wire->name));
78  } else {
79  if (!report_bits)
80  continue;
81  log(" found wire with stub bits: %s [", RTLIL::id2cstr(wire->name));
82  for (int bit : stub_bits)
83  log("%s%d", bit == *stub_bits.begin() ? "" : ", ", bit);
84  log("]\n");
85  }
86 
87  // we have outputted a line, increment summary counter
88  line_count++;
89  }
90 
91  // report summary
92  if (report_bits)
93  log(" found %d stub wires or wires with stub bits.\n", line_count);
94  else
95  log(" found %d stub wires.\n", line_count);
96 }
97 
98 // each pass contains a singleton object that is derived from Pass
99 struct StubnetsPass : public Pass {
100  StubnetsPass() : Pass("stubnets") { }
101  virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
102  {
103  // variables to mirror information from passed options
104  bool report_bits = 0;
105 
106  log_header("Executing STUBNETS pass (find stub nets).\n");
107 
108  // parse options
109  size_t argidx;
110  for (argidx = 1; argidx < args.size(); argidx++) {
111  std::string arg = args[argidx];
112  if (arg == "-report_bits") {
113  report_bits = true;
114  continue;
115  }
116  break;
117  }
118 
119  // handle extra options (e.g. selection)
120  extra_args(args, argidx, design);
121 
122  // call find_stub_nets() for each module that is either
123  // selected as a whole or contains selected objects.
124  for (auto &it : design->modules_)
125  if (design->selected_module(it.first))
126  find_stub_nets(design, it.second, report_bits);
127  }
128 } StubnetsPass;
129 
bool selected(T1 *module) const
Definition: rtlil.h:551
bool selected_module(RTLIL::IdString mod_name) const
Definition: rtlil.cc:379
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
Definition: stubnets.cc:101
void log_header(const char *format,...)
Definition: log.cc:188
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
Definition: rtlil.h:595
RTLIL::Module * module
Definition: abc.cc:94
int port_id
Definition: rtlil.h:826
StubnetsPass StubnetsPass
#define PRIVATE_NAMESPACE_BEGIN
Definition: yosys.h:97
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
RTLIL::IdString name
Definition: rtlil.h:599
#define PRIVATE_NAMESPACE_END
Definition: yosys.h:98
Definition: register.h:27
RTLIL::IdString name
Definition: rtlil.h:825
static const char * id2cstr(const RTLIL::IdString &str)
Definition: rtlil.h:267
#define USING_YOSYS_NAMESPACE
Definition: yosys.h:102
std::map< RTLIL::IdString, RTLIL::Module * > modules_
Definition: rtlil.h:507
USING_YOSYS_NAMESPACE static PRIVATE_NAMESPACE_BEGIN void find_stub_nets(RTLIL::Design *design, RTLIL::Module *module, bool report_bits)
Definition: stubnets.cc:19
#define NULL
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
Definition: rtlil.h:596
void log(const char *format,...)
Definition: log.cc:180
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
Definition: register.cc:128