yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
stat.cc
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 #include "kernel/register.h"
21 #include "kernel/celltypes.h"
22 #include "kernel/log.h"
23 
26 
27 struct statdata_t
28 {
29  #define STAT_INT_MEMBERS X(num_wires) X(num_wire_bits) X(num_pub_wires) X(num_pub_wire_bits) \
30  X(num_memories) X(num_memory_bits) X(num_cells) X(num_processes)
31 
32  #define X(_name) int _name;
34  #undef X
35 
36  std::map<RTLIL::IdString, int, RTLIL::sort_by_id_str> num_cells_by_type;
37 
38  statdata_t operator+(const statdata_t &other) const
39  {
40  statdata_t sum = other;
41  #define X(_name) sum._name += _name;
43  #undef X
44  for (auto &it : num_cells_by_type)
45  sum.num_cells_by_type[it.first] += it.second;
46  return sum;
47  }
48 
49  statdata_t operator*(int other) const
50  {
51  statdata_t sum = *this;
52  #define X(_name) sum._name *= other;
54  #undef X
55  for (auto &it : sum.num_cells_by_type)
56  it.second *= other;
57  return sum;
58  }
59 
61  {
62  #define X(_name) _name = 0;
64  #undef X
65  }
66 
67  statdata_t(RTLIL::Design *design, RTLIL::Module *mod, bool width_mode)
68  {
69  #define X(_name) _name = 0;
71  #undef X
72 
73  for (auto &it : mod->wires_)
74  {
75  if (!design->selected(mod, it.second))
76  continue;
77 
78  if (it.first[0] == '\\') {
79  num_pub_wires++;
80  num_pub_wire_bits += it.second->width;
81  }
82 
83  num_wires++;
84  num_wire_bits += it.second->width;
85  }
86 
87  for (auto &it : mod->memories) {
88  if (!design->selected(mod, it.second))
89  continue;
90  num_memories++;
91  num_memory_bits += it.second->width * it.second->size;
92  }
93 
94  for (auto &it : mod->cells_)
95  {
96  if (!design->selected(mod, it.second))
97  continue;
98 
99  RTLIL::IdString cell_type = it.second->type;
100 
101  if (width_mode)
102  {
103  if (cell_type.in("$not", "$pos", "$neg",
104  "$logic_not", "$logic_and", "$logic_or",
105  "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool",
106  "$lut", "$and", "$or", "$xor", "$xnor",
107  "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
108  "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
109  "$add", "$sub", "$mul", "$div", "$mod", "$pow")) {
110  int width_a = it.second->hasPort("\\A") ? GetSize(it.second->getPort("\\A")) : 0;
111  int width_b = it.second->hasPort("\\B") ? GetSize(it.second->getPort("\\B")) : 0;
112  int width_y = it.second->hasPort("\\Y") ? GetSize(it.second->getPort("\\Y")) : 0;
113  cell_type = stringf("%s_%d", cell_type.c_str(), std::max<int>({width_a, width_b, width_y}));
114  }
115  else if (cell_type.in("$mux", "$pmux"))
116  cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort("\\Y")));
117  else if (cell_type.in("$sr", "$dff", "$dffsr", "$adff", "$dlatch", "$dlatchsr"))
118  cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort("\\Q")));
119  }
120 
121  num_cells++;
122  num_cells_by_type[cell_type]++;
123  }
124 
125  for (auto &it : mod->processes) {
126  if (!design->selected(mod, it.second))
127  continue;
128  num_processes++;
129  }
130  }
131 
132  void log_data()
133  {
134  log(" Number of wires: %6d\n", num_wires);
135  log(" Number of wire bits: %6d\n", num_wire_bits);
136  log(" Number of public wires: %6d\n", num_pub_wires);
137  log(" Number of public wire bits: %6d\n", num_pub_wire_bits);
138  log(" Number of memories: %6d\n", num_memories);
139  log(" Number of memory bits: %6d\n", num_memory_bits);
140  log(" Number of processes: %6d\n", num_processes);
141  log(" Number of cells: %6d\n", num_cells);
142  for (auto &it : num_cells_by_type)
143  log(" %-26s %6d\n", RTLIL::id2cstr(it.first), it.second);
144  }
145 };
146 
147 statdata_t hierarchy_worker(std::map<RTLIL::IdString, statdata_t> &mod_stat, RTLIL::IdString mod, int level)
148 {
149  statdata_t mod_data = mod_stat.at(mod);
150  std::map<RTLIL::IdString, int, RTLIL::sort_by_id_str> num_cells_by_type;
151  num_cells_by_type.swap(mod_data.num_cells_by_type);
152 
153  for (auto &it : num_cells_by_type)
154  if (mod_stat.count(it.first) > 0) {
155  log(" %*s%-*s %6d\n", 2*level, "", 26-2*level, RTLIL::id2cstr(it.first), it.second);
156  mod_data = mod_data + hierarchy_worker(mod_stat, it.first, level+1) * it.second;
157  mod_data.num_cells -= it.second;
158  } else {
159  mod_data.num_cells_by_type[it.first] += it.second;
160  }
161 
162  return mod_data;
163 }
164 
165 struct StatPass : public Pass {
166  StatPass() : Pass("stat", "print some statistics") { }
167  virtual void help()
168  {
169  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
170  log("\n");
171  log(" stat [options] [selection]\n");
172  log("\n");
173  log("Print some statistics (number of objects) on the selected portion of the\n");
174  log("design.\n");
175  log("\n");
176  log(" -top <module>\n");
177  log(" print design hierarchy with this module as top. if the design is fully\n");
178  log(" selected and a module has the 'top' attribute set, this module is used\n");
179  log(" default value for this option.\n");
180  log("\n");
181  log(" -width\n");
182  log(" annotate internal cell types with their word width.\n");
183  log(" e.g. $add_8 for an 8 bit wide $add cell.\n");
184  log("\n");
185  }
186  virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
187  {
188  log_header("Printing statistics.\n");
189 
190  bool width_mode = false;
191  RTLIL::Module *top_mod = NULL;
192  std::map<RTLIL::IdString, statdata_t> mod_stat;
193 
194  size_t argidx;
195  for (argidx = 1; argidx < args.size(); argidx++)
196  {
197  if (args[argidx] == "-width") {
198  width_mode = true;
199  continue;
200  }
201  if (args[argidx] == "-top" && argidx+1 < args.size()) {
202  if (design->modules_.count(RTLIL::escape_id(args[argidx+1])) == 0)
203  log_cmd_error("Can't find module %s.\n", args[argidx+1].c_str());
204  top_mod = design->modules_.at(RTLIL::escape_id(args[++argidx]));
205  continue;
206  }
207  break;
208  }
209  extra_args(args, argidx, design);
210 
211  for (auto &it : design->modules_)
212  {
213  if (!design->selected_module(it.first))
214  continue;
215 
216  if (!top_mod && design->full_selection())
217  if (it.second->get_bool_attribute("\\top"))
218  top_mod = it.second;
219 
220  statdata_t data(design, it.second, width_mode);
221  mod_stat[it.first] = data;
222 
223  log("\n");
224  log("=== %s%s ===\n", RTLIL::id2cstr(it.first), design->selected_whole_module(it.first) ? "" : " (partially selected)");
225  log("\n");
226  data.log_data();
227  }
228 
229  if (top_mod != NULL)
230  {
231  log("\n");
232  log("=== design hierarchy ===\n");
233  log("\n");
234 
235  log(" %-28s %6d\n", RTLIL::id2cstr(top_mod->name), 1);
236  statdata_t data = hierarchy_worker(mod_stat, top_mod->name, 0);
237 
238  log("\n");
239  data.log_data();
240  }
241 
242  log("\n");
243  }
244 } StatPass;
245 
const char * c_str() const
Definition: rtlil.h:178
bool selected(T1 *module) const
Definition: rtlil.h:551
std::string stringf(const char *fmt,...)
Definition: yosys.cc:58
void log_data()
Definition: stat.cc:132
bool selected_module(RTLIL::IdString mod_name) const
Definition: rtlil.cc:379
void log_header(const char *format,...)
Definition: log.cc:188
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
Definition: rtlil.h:595
std::map< RTLIL::IdString, RTLIL::Memory * > memories
Definition: rtlil.h:601
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
Definition: stat.cc:186
bool in(T first, Args...rest)
Definition: rtlil.h:241
static std::string escape_id(std::string str)
Definition: rtlil.h:251
StatPass()
Definition: stat.cc:166
StatPass StatPass
bool full_selection() const
Definition: rtlil.h:547
#define PRIVATE_NAMESPACE_BEGIN
Definition: yosys.h:97
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
RTLIL::IdString name
Definition: rtlil.h:599
statdata_t()
Definition: stat.cc:60
bool selected_whole_module(RTLIL::IdString mod_name) const
Definition: rtlil.cc:388
statdata_t(RTLIL::Design *design, RTLIL::Module *mod, bool width_mode)
Definition: stat.cc:67
statdata_t hierarchy_worker(std::map< RTLIL::IdString, statdata_t > &mod_stat, RTLIL::IdString mod, int level)
Definition: stat.cc:147
#define PRIVATE_NAMESPACE_END
Definition: yosys.h:98
STAT_INT_MEMBERS std::map< RTLIL::IdString, int, RTLIL::sort_by_id_str > num_cells_by_type
Definition: stat.cc:36
Definition: register.h:27
static const char * id2cstr(const RTLIL::IdString &str)
Definition: rtlil.h:267
void log_cmd_error(const char *format,...)
Definition: log.cc:211
std::map< RTLIL::IdString, RTLIL::Process * > processes
Definition: rtlil.h:602
virtual void help()
Definition: stat.cc:167
#define USING_YOSYS_NAMESPACE
Definition: yosys.h:102
std::map< RTLIL::IdString, RTLIL::Module * > modules_
Definition: rtlil.h:507
#define NULL
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
Definition: rtlil.h:596
void log(const char *format,...)
Definition: log.cc:180
#define STAT_INT_MEMBERS
Definition: stat.cc:29
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
Definition: register.cc:128
statdata_t operator*(int other) const
Definition: stat.cc:49
statdata_t operator+(const statdata_t &other) const
Definition: stat.cc:38