yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
OptShareWorker Struct Reference
+ Collaboration diagram for OptShareWorker:

Data Structures

struct  CompareCells
 

Public Member Functions

std::string int_to_hash_string (unsigned int v)
 
std::string hash_cell_parameters_and_connections (const RTLIL::Cell *cell)
 
bool compare_cell_parameters_and_connections (const RTLIL::Cell *cell1, const RTLIL::Cell *cell2, bool &lt)
 
bool compare_cells (const RTLIL::Cell *cell1, const RTLIL::Cell *cell2)
 
 OptShareWorker (RTLIL::Design *design, RTLIL::Module *module, bool mode_nomux)
 

Data Fields

RTLIL::Designdesign
 
RTLIL::Modulemodule
 
SigMap assign_map
 
SigMap dff_init_map
 
CellTypes ct
 
int total_count
 
std::map< const RTLIL::Cell
*, std::string > 
cell_hash_cache
 

Detailed Description

Definition at line 34 of file opt_share.cc.

Constructor & Destructor Documentation

OptShareWorker::OptShareWorker ( RTLIL::Design design,
RTLIL::Module module,
bool  mode_nomux 
)
inline

Definition at line 217 of file opt_share.cc.

217  :
218  design(design), module(module), assign_map(module)
219  {
220  total_count = 0;
223  ct.setup_stdcells();
225 
226  if (mode_nomux) {
227  ct.cell_types.erase("$mux");
228  ct.cell_types.erase("$pmux");
229  }
230 
231  log("Finding identical cells in module `%s'.\n", module->name.c_str());
232  assign_map.set(module);
233 
234  dff_init_map.set(module);
235  for (auto &it : module->wires_)
236  if (it.second->attributes.count("\\init") != 0)
237  dff_init_map.add(it.second, it.second->attributes.at("\\init"));
238 
239  bool did_something = true;
240  while (did_something)
241  {
242 #ifdef USE_CELL_HASH_CACHE
243  cell_hash_cache.clear();
244 #endif
245  std::vector<RTLIL::Cell*> cells;
246  cells.reserve(module->cells_.size());
247  for (auto &it : module->cells_) {
248  if (ct.cell_known(it.second->type) && design->selected(module, it.second))
249  cells.push_back(it.second);
250  }
251 
252  did_something = false;
253  std::map<RTLIL::Cell*, RTLIL::Cell*, CompareCells> sharemap(CompareCells(this));
254  for (auto cell : cells)
255  {
256  if (sharemap.count(cell) > 0) {
257  did_something = true;
258  log(" Cell `%s' is identical to cell `%s'.\n", cell->name.c_str(), sharemap[cell]->name.c_str());
259  for (auto &it : cell->connections()) {
260  if (ct.cell_output(cell->type, it.first)) {
261  RTLIL::SigSpec other_sig = sharemap[cell]->getPort(it.first);
262  log(" Redirecting output %s: %s = %s\n", it.first.c_str(),
263  log_signal(it.second), log_signal(other_sig));
264  module->connect(RTLIL::SigSig(it.second, other_sig));
265  assign_map.add(it.second, other_sig);
266  }
267  }
268  log(" Removing %s cell `%s' from module `%s'.\n", cell->type.c_str(), cell->name.c_str(), module->name.c_str());
269  module->remove(cell);
270  total_count++;
271  } else {
272  sharemap[cell] = cell;
273  }
274  }
275  }
276  }
const char * c_str() const
Definition: rtlil.h:178
bool selected(T1 *module) const
Definition: rtlil.h:551
void setup_stdcells()
Definition: celltypes.h:132
void setup_internals_mem()
Definition: celltypes.h:115
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
Definition: rtlil.h:595
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
RTLIL::Module * module
Definition: opt_share.cc:37
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool did_something
Definition: opt_const.cc:32
std::map< RTLIL::IdString, CellType > cell_types
Definition: celltypes.h:36
void set(RTLIL::Module *module)
Definition: sigtools.h:273
bool cell_known(RTLIL::IdString type)
Definition: celltypes.h:188
void connect(const RTLIL::SigSig &conn)
Definition: rtlil.cc:1278
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
Definition: celltypes.h:193
SigMap assign_map
Definition: opt_share.cc:38
RTLIL::IdString name
Definition: rtlil.h:599
SigMap dff_init_map
Definition: opt_share.cc:39
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
Definition: rtlil.h:596
void remove(const std::set< RTLIL::Wire * > &wires)
Definition: rtlil.cc:1158
CellTypes ct
Definition: opt_share.cc:41
void log(const char *format,...)
Definition: log.cc:180
void setup_internals()
Definition: celltypes.h:83
void setup_stdcells_mem()
Definition: celltypes.h:149
void add(RTLIL::SigSpec from, RTLIL::SigSpec to)
Definition: sigtools.h:347
std::map< const RTLIL::Cell *, std::string > cell_hash_cache
Definition: opt_share.cc:44
std::pair< SigSpec, SigSpec > SigSig
Definition: rtlil.h:71
RTLIL::Design * design
Definition: opt_share.cc:36

+ Here is the call graph for this function:

Member Function Documentation

bool OptShareWorker::compare_cell_parameters_and_connections ( const RTLIL::Cell cell1,
const RTLIL::Cell cell2,
bool &  lt 
)
inline

Definition at line 117 of file opt_share.cc.

118  {
119 #ifdef USE_CELL_HASH_CACHE
120  std::string hash1 = hash_cell_parameters_and_connections(cell1);
121  std::string hash2 = hash_cell_parameters_and_connections(cell2);
122 
123  if (hash1 != hash2) {
124  lt = hash1 < hash2;
125  return true;
126  }
127 #endif
128 
129  if (cell1->parameters != cell2->parameters) {
130  lt = cell1->parameters < cell2->parameters;
131  return true;
132  }
133 
134  std::map<RTLIL::IdString, RTLIL::SigSpec> conn1 = cell1->connections();
135  std::map<RTLIL::IdString, RTLIL::SigSpec> conn2 = cell2->connections();
136 
137  for (auto &it : conn1) {
138  if (ct.cell_output(cell1->type, it.first))
139  it.second = RTLIL::SigSpec();
140  else
141  assign_map.apply(it.second);
142  }
143 
144  for (auto &it : conn2) {
145  if (ct.cell_output(cell2->type, it.first))
146  it.second = RTLIL::SigSpec();
147  else
148  assign_map.apply(it.second);
149  }
150 
151  if (cell1->type == "$and" || cell1->type == "$or" || cell1->type == "$xor" || cell1->type == "$xnor" || cell1->type == "$add" || cell1->type == "$mul" ||
152  cell1->type == "$logic_and" || cell1->type == "$logic_or" || cell1->type == "$_AND_" || cell1->type == "$_OR_" || cell1->type == "$_XOR_") {
153  if (conn1.at("\\A") < conn1.at("\\B")) {
154  RTLIL::SigSpec tmp = conn1["\\A"];
155  conn1["\\A"] = conn1["\\B"];
156  conn1["\\B"] = tmp;
157  }
158  if (conn2.at("\\A") < conn2.at("\\B")) {
159  RTLIL::SigSpec tmp = conn2["\\A"];
160  conn2["\\A"] = conn2["\\B"];
161  conn2["\\B"] = tmp;
162  }
163  } else
164  if (cell1->type == "$reduce_xor" || cell1->type == "$reduce_xnor") {
165  conn1["\\A"].sort();
166  conn2["\\A"].sort();
167  } else
168  if (cell1->type == "$reduce_and" || cell1->type == "$reduce_or" || cell1->type == "$reduce_bool") {
169  conn1["\\A"].sort_and_unify();
170  conn2["\\A"].sort_and_unify();
171  }
172 
173  if (conn1 != conn2) {
174  lt = conn1 < conn2;
175  return true;
176  }
177 
178  if (cell1->type.substr(0, 1) == "$" && conn1.count("\\Q") != 0) {
179  std::vector<RTLIL::SigBit> q1 = dff_init_map(cell1->getPort("\\Q")).to_sigbit_vector();
180  std::vector<RTLIL::SigBit> q2 = dff_init_map(cell2->getPort("\\Q")).to_sigbit_vector();
181  for (size_t i = 0; i < q1.size(); i++)
182  if ((q1.at(i).wire == NULL || q2.at(i).wire == NULL) && q1.at(i) != q2.at(i)) {
183  lt = q1.at(i) < q2.at(i);
184  return true;
185  }
186  }
187 
188  return false;
189  }
void sort()
Definition: rtlil.cc:2284
RTLIL::IdString type
Definition: rtlil.h:854
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856
void apply(RTLIL::SigBit &bit) const
Definition: sigtools.h:383
std::string hash_cell_parameters_and_connections(const RTLIL::Cell *cell)
Definition: opt_share.cc:60
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
Definition: celltypes.h:193
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
Definition: rtlil.cc:1809
SigMap assign_map
Definition: opt_share.cc:38
SigMap dff_init_map
Definition: opt_share.cc:39
std::string substr(size_t pos=0, size_t len=std::string::npos) const
Definition: rtlil.h:208
#define NULL
CellTypes ct
Definition: opt_share.cc:41
const std::map< RTLIL::IdString, RTLIL::SigSpec > & connections() const
Definition: rtlil.cc:1814

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool OptShareWorker::compare_cells ( const RTLIL::Cell cell1,
const RTLIL::Cell cell2 
)
inline

Definition at line 191 of file opt_share.cc.

192  {
193  if (cell1->type != cell2->type)
194  return cell1->type < cell2->type;
195 
196  if (!ct.cell_known(cell1->type))
197  return cell1 < cell2;
198 
199  if (cell1->has_keep_attr() || cell2->has_keep_attr())
200  return cell1 < cell2;
201 
202  bool lt;
203  if (compare_cell_parameters_and_connections(cell1, cell2, lt))
204  return lt;
205 
206  return false;
207  }
RTLIL::IdString type
Definition: rtlil.h:854
bool cell_known(RTLIL::IdString type)
Definition: celltypes.h:188
CellTypes ct
Definition: opt_share.cc:41
bool compare_cell_parameters_and_connections(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2, bool &lt)
Definition: opt_share.cc:117
bool has_keep_attr() const
Definition: rtlil.h:875

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string OptShareWorker::hash_cell_parameters_and_connections ( const RTLIL::Cell cell)
inline

Definition at line 60 of file opt_share.cc.

61  {
62  if (cell_hash_cache.count(cell) > 0)
63  return cell_hash_cache[cell];
64 
65  std::string hash_string = cell->type.str() + "\n";
66 
67  for (auto &it : cell->parameters)
68  hash_string += "P " + it.first.str() + "=" + it.second.as_string() + "\n";
69 
70  const std::map<RTLIL::IdString, RTLIL::SigSpec> *conn = &cell->connections();
71  std::map<RTLIL::IdString, RTLIL::SigSpec> alt_conn;
72 
73  if (cell->type == "$and" || cell->type == "$or" || cell->type == "$xor" || cell->type == "$xnor" || cell->type == "$add" || cell->type == "$mul" ||
74  cell->type == "$logic_and" || cell->type == "$logic_or" || cell->type == "$_AND_" || cell->type == "$_OR_" || cell->type == "$_XOR_") {
75  alt_conn = *conn;
76  if (assign_map(alt_conn.at("\\A")) < assign_map(alt_conn.at("\\B"))) {
77  alt_conn["\\A"] = conn->at("\\B");
78  alt_conn["\\B"] = conn->at("\\A");
79  }
80  conn = &alt_conn;
81  } else
82  if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor") {
83  alt_conn = *conn;
84  assign_map.apply(alt_conn.at("\\A"));
85  alt_conn.at("\\A").sort();
86  conn = &alt_conn;
87  } else
88  if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_bool") {
89  alt_conn = *conn;
90  assign_map.apply(alt_conn.at("\\A"));
91  alt_conn.at("\\A").sort_and_unify();
92  conn = &alt_conn;
93  }
94 
95  for (auto &it : *conn) {
96  if (ct.cell_output(cell->type, it.first))
97  continue;
98  RTLIL::SigSpec sig = it.second;
99  assign_map.apply(sig);
100  hash_string += "C " + it.first.str() + "=";
101  for (auto &chunk : sig.chunks()) {
102  if (chunk.wire)
103  hash_string += "{" + chunk.wire->name.str() + " " +
104  int_to_hash_string(chunk.offset) + " " +
105  int_to_hash_string(chunk.width) + "}";
106  else
107  hash_string += RTLIL::Const(chunk.data).as_string();
108  }
109  hash_string += "\n";
110  }
111 
112  cell_hash_cache[cell] = sha1(hash_string);
113  return cell_hash_cache[cell];
114  }
std::string str() const
Definition: rtlil.h:182
RTLIL::IdString type
Definition: rtlil.h:854
std::map< RTLIL::IdString, RTLIL::Const > parameters
Definition: rtlil.h:856
void apply(RTLIL::SigBit &bit) const
Definition: sigtools.h:383
std::string int_to_hash_string(unsigned int v)
Definition: opt_share.cc:48
std::string as_string() const
Definition: rtlil.cc:116
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
Definition: celltypes.h:193
SigMap assign_map
Definition: opt_share.cc:38
CellTypes ct
Definition: opt_share.cc:41
std::string sha1(const std::string &string)
Definition: sha1.cpp:270
std::map< const RTLIL::Cell *, std::string > cell_hash_cache
Definition: opt_share.cc:44
const std::map< RTLIL::IdString, RTLIL::SigSpec > & connections() const
Definition: rtlil.cc:1814
const std::vector< RTLIL::SigChunk > & chunks() const
Definition: rtlil.h:1016

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string OptShareWorker::int_to_hash_string ( unsigned int  v)
inline

Definition at line 48 of file opt_share.cc.

49  {
50  if (v == 0)
51  return "0";
52  std::string str = "";
53  while (v > 0) {
54  str += 'a' + (v & 15);
55  v = v >> 4;
56  }
57  return str;
58  }

+ Here is the caller graph for this function:

Field Documentation

SigMap OptShareWorker::assign_map

Definition at line 38 of file opt_share.cc.

std::map<const RTLIL::Cell*, std::string> OptShareWorker::cell_hash_cache

Definition at line 44 of file opt_share.cc.

CellTypes OptShareWorker::ct

Definition at line 41 of file opt_share.cc.

RTLIL::Design* OptShareWorker::design

Definition at line 36 of file opt_share.cc.

SigMap OptShareWorker::dff_init_map

Definition at line 39 of file opt_share.cc.

RTLIL::Module* OptShareWorker::module

Definition at line 37 of file opt_share.cc.

int OptShareWorker::total_count

Definition at line 42 of file opt_share.cc.


The documentation for this struct was generated from the following file: