yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
techmap.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/yosys.h"
21 #include "kernel/utils.h"
22 #include "kernel/sigtools.h"
23 #include "libs/sha1/sha1.h"
24 
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 
30 
32 
33 // see simplemap.cc
34 extern void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> &mappers);
35 
36 // see maccmap.cc
37 extern void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap = false);
38 
40 
43 
44 void apply_prefix(std::string prefix, std::string &id)
45 {
46  if (id[0] == '\\')
47  id = prefix + "." + id.substr(1);
48  else
49  id = "$techmap" + prefix + "." + id;
50 }
51 
52 void apply_prefix(std::string prefix, RTLIL::SigSpec &sig, RTLIL::Module *module)
53 {
54  std::vector<RTLIL::SigChunk> chunks = sig;
55  for (auto &chunk : chunks)
56  if (chunk.wire != NULL) {
57  std::string wire_name = chunk.wire->name.str();
58  apply_prefix(prefix, wire_name);
59  log_assert(module->wires_.count(wire_name) > 0);
60  chunk.wire = module->wires_[wire_name];
61  }
62  sig = chunks;
63 }
64 
66 {
67  std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> simplemap_mappers;
68  std::map<std::pair<RTLIL::IdString, std::map<RTLIL::IdString, RTLIL::Const>>, RTLIL::Module*> techmap_cache;
69  std::map<RTLIL::Module*, bool> techmap_do_cache;
70  std::set<RTLIL::Module*, RTLIL::IdString::compare_ptr_by_name<RTLIL::Module>> module_queue;
71 
72  struct TechmapWireData {
75  };
76 
77  typedef std::map<std::string, std::vector<TechmapWireData>> TechmapWires;
78 
84 
86  {
87  extern_mode = false;
88  assert_mode = false;
89  flatten_mode = false;
90  recursive_mode = false;
91  autoproc_mode = false;
92  }
93 
94  std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose)
95  {
96  std::string constmap_info;
97  std::map<RTLIL::SigBit, std::pair<RTLIL::IdString, int>> connbits_map;
98 
99  for (auto conn : cell->connections())
100  for (int i = 0; i < GetSize(conn.second); i++) {
101  RTLIL::SigBit bit = sigmap(conn.second[i]);
102  if (bit.wire == nullptr) {
103  if (verbose)
104  log(" Constant input on bit %d of port %s: %s\n", i, log_id(conn.first), log_signal(bit));
105  constmap_info += stringf("|%s %d %d", log_id(conn.first), i, bit.data);
106  } else if (connbits_map.count(bit)) {
107  if (verbose)
108  log(" Bit %d of port %s and bit %d of port %s are connected.\n", i, log_id(conn.first),
109  connbits_map.at(bit).second, log_id(connbits_map.at(bit).first));
110  constmap_info += stringf("|%s %d %s %d", log_id(conn.first), i,
111  log_id(connbits_map.at(bit).first), connbits_map.at(bit).second);
112  } else {
113  connbits_map[bit] = std::pair<RTLIL::IdString, int>(conn.first, i);
114  constmap_info += stringf("|%s %d", log_id(conn.first), i);
115  }
116  }
117 
118  return stringf("$paramod$constmap:%s%s", sha1(constmap_info).c_str(), tpl->name.c_str());
119  }
120 
122  {
123  TechmapWires result;
124 
125  if (module == NULL)
126  return result;
127 
128  for (auto &it : module->wires_) {
129  const char *p = it.first.c_str();
130  if (*p == '$')
131  continue;
132 
133  const char *q = strrchr(p+1, '.');
134  p = q ? q : p+1;
135 
136  if (!strncmp(p, "_TECHMAP_", 9)) {
137  TechmapWireData record;
138  record.wire = it.second;
139  record.value = it.second;
140  result[p].push_back(record);
141  it.second->attributes["\\keep"] = RTLIL::Const(1);
142  it.second->attributes["\\_techmap_special_"] = RTLIL::Const(1);
143  }
144  }
145 
146  if (!result.empty()) {
147  SigMap sigmap(module);
148  for (auto &it1 : result)
149  for (auto &it2 : it1.second)
150  sigmap.apply(it2.value);
151  }
152 
153  return result;
154  }
155 
157  {
158  if (tpl->memories.size() != 0)
159  log_error("Technology map yielded memories -> this is not supported.\n");
160 
161  if (tpl->processes.size() != 0) {
162  log("Technology map yielded processes:\n");
163  for (auto &it : tpl->processes)
164  log(" %s",RTLIL::id2cstr(it.first));
165  if (autoproc_mode) {
166  Pass::call_on_module(tpl->design, tpl, "proc");
167  log_assert(GetSize(tpl->processes) == 0);
168  } else
169  log_error("Technology map yielded processes -> this is not supported (use -autoproc to run 'proc' automatically).\n");
170  }
171 
172  std::string orig_cell_name;
173  if (!flatten_mode)
174  for (auto &it : tpl->cells_)
175  if (it.first == "\\_TECHMAP_REPLACE_") {
176  orig_cell_name = cell->name.str();
177  module->rename(cell, stringf("$techmap%d", autoidx++) + cell->name.str());
178  break;
179  }
180 
181  std::map<RTLIL::IdString, RTLIL::IdString> positional_ports;
182 
183  for (auto &it : tpl->wires_) {
184  if (it.second->port_id > 0)
185  positional_ports[stringf("$%d", it.second->port_id)] = it.first;
186  std::string w_name = it.second->name.str();
187  apply_prefix(cell->name.str(), w_name);
188  RTLIL::Wire *w = module->addWire(w_name, it.second);
189  w->port_input = false;
190  w->port_output = false;
191  w->port_id = 0;
192  if (it.second->get_bool_attribute("\\_techmap_special_"))
193  w->attributes.clear();
194  design->select(module, w);
195  }
196 
197  SigMap port_signal_map;
198 
199  for (auto &it : cell->connections()) {
200  RTLIL::IdString portname = it.first;
201  if (positional_ports.count(portname) > 0)
202  portname = positional_ports.at(portname);
203  if (tpl->wires_.count(portname) == 0 || tpl->wires_.at(portname)->port_id == 0) {
204  if (portname.substr(0, 1) == "$")
205  log_error("Can't map port `%s' of cell `%s' to template `%s'!\n", portname.c_str(), cell->name.c_str(), tpl->name.c_str());
206  continue;
207  }
208  RTLIL::Wire *w = tpl->wires_.at(portname);
209  RTLIL::SigSig c;
210  if (w->port_output) {
211  c.first = it.second;
212  c.second = RTLIL::SigSpec(w);
213  apply_prefix(cell->name.str(), c.second, module);
214  } else {
215  c.first = RTLIL::SigSpec(w);
216  c.second = it.second;
217  apply_prefix(cell->name.str(), c.first, module);
218  }
219  if (c.second.size() > c.first.size())
220  c.second.remove(c.first.size(), c.second.size() - c.first.size());
221  if (c.second.size() < c.first.size())
222  c.second.append(RTLIL::SigSpec(RTLIL::State::S0, c.first.size() - c.second.size()));
223  log_assert(c.first.size() == c.second.size());
224  if (flatten_mode) {
225  // more conservative approach:
226  // connect internal and external wires
227  module->connect(c);
228  } else {
229  // approach that yields nicer outputs:
230  // replace internal wires that are connected to external wires
231  if (w->port_output)
232  port_signal_map.add(c.second, c.first);
233  else
234  port_signal_map.add(c.first, c.second);
235  }
236  }
237 
238  for (auto &it : tpl->cells_)
239  {
240  std::string c_name = it.second->name.str();
241 
242  if (!flatten_mode && c_name == "\\_TECHMAP_REPLACE_")
243  c_name = orig_cell_name;
244  else
245  apply_prefix(cell->name.str(), c_name);
246 
247  RTLIL::Cell *c = module->addCell(c_name, it.second);
248  design->select(module, c);
249 
250  if (!flatten_mode && c->type.substr(0, 2) == "\\$")
251  c->type = c->type.substr(1);
252 
253  for (auto &it2 : c->connections_) {
254  apply_prefix(cell->name.str(), it2.second, module);
255  port_signal_map.apply(it2.second);
256  }
257  }
258 
259  for (auto &it : tpl->connections()) {
260  RTLIL::SigSig c = it;
261  apply_prefix(cell->name.str(), c.first, module);
262  apply_prefix(cell->name.str(), c.second, module);
263  port_signal_map.apply(c.first);
264  port_signal_map.apply(c.second);
265  module->connect(c);
266  }
267 
268  module->remove(cell);
269  }
270 
271  bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set<RTLIL::Cell*> &handled_cells,
272  const std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> &celltypeMap, bool in_recursion)
273  {
274  std::string mapmsg_prefix = in_recursion ? "Recursively mapping" : "Mapping";
275 
276  if (!design->selected(module))
277  return false;
278 
279  bool log_continue = false;
280  bool did_something = false;
281 
282  SigMap sigmap(module);
283 
285  std::map<RTLIL::Cell*, std::set<RTLIL::SigBit>> cell_to_inbit;
286  std::map<RTLIL::SigBit, std::set<RTLIL::Cell*>> outbit_to_cell;
287 
288  for (auto cell : module->cells())
289  {
290  if (!design->selected(module, cell) || handled_cells.count(cell) > 0)
291  continue;
292 
293  std::string cell_type = cell->type.str();
294  if (in_recursion && cell_type.substr(0, 2) == "\\$")
295  cell_type = cell_type.substr(1);
296 
297  if (celltypeMap.count(cell_type) == 0) {
298  if (assert_mode && cell_type.back() != '_')
299  log_error("(ASSERT MODE) No matching template cell for type %s found.\n", log_id(cell_type));
300  continue;
301  }
302 
303  for (auto &conn : cell->connections())
304  {
305  RTLIL::SigSpec sig = sigmap(conn.second);
306  sig.remove_const();
307 
308  if (GetSize(sig) == 0)
309  continue;
310 
311  for (auto &tpl_name : celltypeMap.at(cell_type)) {
312  RTLIL::Module *tpl = map->modules_[tpl_name];
313  RTLIL::Wire *port = tpl->wire(conn.first);
314  if (port && port->port_input)
315  cell_to_inbit[cell].insert(sig.begin(), sig.end());
316  if (port && port->port_output)
317  for (auto &bit : sig)
318  outbit_to_cell[bit].insert(cell);
319  }
320  }
321 
322  cells.node(cell);
323  }
324 
325  for (auto &it_right : cell_to_inbit)
326  for (auto &it_sigbit : it_right.second)
327  for (auto &it_left : outbit_to_cell[it_sigbit])
328  cells.edge(it_left, it_right.first);
329 
330  cells.sort();
331 
332  for (auto cell : cells.sorted)
333  {
334  log_assert(handled_cells.count(cell) == 0);
335  log_assert(cell == module->cell(cell->name));
336  bool mapped_cell = false;
337 
338  std::string cell_type = cell->type.str();
339  if (in_recursion && cell_type.substr(0, 2) == "\\$")
340  cell_type = cell_type.substr(1);
341 
342  for (auto &tpl_name : celltypeMap.at(cell_type))
343  {
344  RTLIL::IdString derived_name = tpl_name;
345  RTLIL::Module *tpl = map->modules_[tpl_name];
346  std::map<RTLIL::IdString, RTLIL::Const> parameters = cell->parameters;
347 
348  if (tpl->get_bool_attribute("\\blackbox"))
349  continue;
350 
351  if (!flatten_mode)
352  {
353  std::string extmapper_name;
354 
355  if (tpl->get_bool_attribute("\\techmap_simplemap"))
356  extmapper_name = "simplemap";
357 
358  if (tpl->get_bool_attribute("\\techmap_maccmap"))
359  extmapper_name = "maccmap";
360 
361  if (tpl->attributes.count("\\techmap_wrap"))
362  extmapper_name = "wrap";
363 
364  if (!extmapper_name.empty())
365  {
366  cell->type = cell_type;
367 
368  if ((extern_mode && !in_recursion) || extmapper_name == "wrap")
369  {
370  std::string m_name = stringf("$extern:%s:%s", extmapper_name.c_str(), log_id(cell->type));
371 
372  for (auto &c : cell->parameters)
373  m_name += stringf(":%s=%s", log_id(c.first), log_signal(c.second));
374 
375  if (extmapper_name == "wrap")
376  m_name += ":" + sha1(tpl->attributes.at("\\techmap_wrap").decode_string());
377 
378  RTLIL::Design *extmapper_design = extern_mode && !in_recursion ? design : tpl->design;
379  RTLIL::Module *extmapper_module = extmapper_design->module(m_name);
380 
381  if (extmapper_module == nullptr)
382  {
383  extmapper_module = extmapper_design->addModule(m_name);
384  RTLIL::Cell *extmapper_cell = extmapper_module->addCell(cell->type, cell);
385 
386  int port_counter = 1;
387  for (auto &c : extmapper_cell->connections_) {
388  RTLIL::Wire *w = extmapper_module->addWire(c.first, GetSize(c.second));
389  if (w->name == "\\Y" || w->name == "\\Q")
390  w->port_output = true;
391  else
392  w->port_input = true;
393  w->port_id = port_counter++;
394  c.second = w;
395  }
396 
397  extmapper_module->fixup_ports();
398  extmapper_module->check();
399 
400  if (extmapper_name == "simplemap") {
401  log("Creating %s with simplemap.\n", log_id(extmapper_module));
402  if (simplemap_mappers.count(extmapper_cell->type) == 0)
403  log_error("No simplemap mapper for cell type %s found!\n", log_id(extmapper_cell->type));
404  simplemap_mappers.at(extmapper_cell->type)(extmapper_module, extmapper_cell);
405  extmapper_module->remove(extmapper_cell);
406  }
407 
408  if (extmapper_name == "maccmap") {
409  log("Creating %s with maccmap.\n", log_id(extmapper_module));
410  if (extmapper_cell->type != "$macc")
411  log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(extmapper_cell->type));
412  maccmap(extmapper_module, extmapper_cell);
413  extmapper_module->remove(extmapper_cell);
414  }
415 
416  if (extmapper_name == "wrap") {
417  std::string cmd_string = tpl->attributes.at("\\techmap_wrap").decode_string();
418  log("Running \"%s\" on wrapper %s.\n", cmd_string.c_str(), log_id(extmapper_module));
419  Pass::call_on_module(extmapper_design, extmapper_module, cmd_string);
420  log_continue = true;
421  }
422  }
423 
424  cell->type = extmapper_module->name;
425  cell->parameters.clear();
426 
427  if (!extern_mode || in_recursion) {
428  tpl = extmapper_module;
429  goto use_wrapper_tpl;
430  }
431 
432  log("%s %s.%s (%s) to %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), log_id(extmapper_module));
433  }
434  else
435  {
436  log("%s %s.%s (%s) with %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(cell->type), extmapper_name.c_str());
437 
438  if (extmapper_name == "simplemap") {
439  if (simplemap_mappers.count(cell->type) == 0)
440  log_error("No simplemap mapper for cell type %s found!\n", RTLIL::id2cstr(cell->type));
441  simplemap_mappers.at(cell->type)(module, cell);
442  }
443 
444  if (extmapper_name == "maccmap") {
445  if (cell->type != "$macc")
446  log_error("The maccmap mapper can only map $macc (not %s) cells!\n", log_id(cell->type));
447  maccmap(module, cell);
448  }
449 
450  module->remove(cell);
451  cell = NULL;
452  }
453 
454  did_something = true;
455  mapped_cell = true;
456  break;
457  }
458 
459  for (auto conn : cell->connections()) {
460  if (conn.first.substr(0, 1) == "$")
461  continue;
462  if (tpl->wires_.count(conn.first) > 0 && tpl->wires_.at(conn.first)->port_id > 0)
463  continue;
464  if (!conn.second.is_fully_const() || parameters.count(conn.first) > 0 || tpl->avail_parameters.count(conn.first) == 0)
465  goto next_tpl;
466  parameters[conn.first] = conn.second.as_const();
467  }
468 
469  if (0) {
470  next_tpl:
471  continue;
472  }
473 
474  if (tpl->avail_parameters.count("\\_TECHMAP_CELLTYPE_") != 0)
475  parameters["\\_TECHMAP_CELLTYPE_"] = RTLIL::unescape_id(cell->type);
476 
477  for (auto conn : cell->connections()) {
478  if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTMSK_%s_", RTLIL::id2cstr(conn.first))) != 0) {
479  std::vector<RTLIL::SigBit> v = sigmap(conn.second).to_sigbit_vector();
480  for (auto &bit : v)
481  bit = RTLIL::SigBit(bit.wire == NULL ? RTLIL::State::S1 : RTLIL::State::S0);
482  parameters[stringf("\\_TECHMAP_CONSTMSK_%s_", RTLIL::id2cstr(conn.first))] = RTLIL::SigSpec(v).as_const();
483  }
484  if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONSTVAL_%s_", RTLIL::id2cstr(conn.first))) != 0) {
485  std::vector<RTLIL::SigBit> v = sigmap(conn.second).to_sigbit_vector();
486  for (auto &bit : v)
487  if (bit.wire != NULL)
489  parameters[stringf("\\_TECHMAP_CONSTVAL_%s_", RTLIL::id2cstr(conn.first))] = RTLIL::SigSpec(v).as_const();
490  }
491  }
492 
493  int unique_bit_id_counter = 0;
494  std::map<RTLIL::SigBit, int> unique_bit_id;
495  unique_bit_id[RTLIL::State::S0] = unique_bit_id_counter++;
496  unique_bit_id[RTLIL::State::S1] = unique_bit_id_counter++;
497  unique_bit_id[RTLIL::State::Sx] = unique_bit_id_counter++;
498  unique_bit_id[RTLIL::State::Sz] = unique_bit_id_counter++;
499 
500  for (auto conn : cell->connections())
501  if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) {
502  for (auto &bit : sigmap(conn.second).to_sigbit_vector())
503  if (unique_bit_id.count(bit) == 0)
504  unique_bit_id[bit] = unique_bit_id_counter++;
505  }
506 
507  int bits = 0;
508  for (int i = 0; i < 32; i++)
509  if (((unique_bit_id_counter-1) & (1 << i)) != 0)
510  bits = i;
511  if (tpl->avail_parameters.count("\\_TECHMAP_BITS_CONNMAP_"))
512  parameters["\\_TECHMAP_BITS_CONNMAP_"] = bits;
513 
514  for (auto conn : cell->connections())
515  if (tpl->avail_parameters.count(stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))) != 0) {
516  RTLIL::Const value;
517  for (auto &bit : sigmap(conn.second).to_sigbit_vector()) {
518  RTLIL::Const chunk(unique_bit_id.at(bit), bits);
519  value.bits.insert(value.bits.end(), chunk.bits.begin(), chunk.bits.end());
520  }
521  parameters[stringf("\\_TECHMAP_CONNMAP_%s_", RTLIL::id2cstr(conn.first))] = value;
522  }
523  }
524 
525  if (0) {
526  use_wrapper_tpl:;
527  // do not register techmap_wrap modules with techmap_cache
528  } else {
529  std::pair<RTLIL::IdString, std::map<RTLIL::IdString, RTLIL::Const>> key(tpl_name, parameters);
530  if (techmap_cache.count(key) > 0) {
531  tpl = techmap_cache[key];
532  } else {
533  if (cell->parameters.size() != 0) {
534  derived_name = tpl->derive(map, parameters);
535  tpl = map->module(derived_name);
536  log_continue = true;
537  }
538  techmap_cache[key] = tpl;
539  }
540  }
541 
542  if (flatten_mode) {
543  techmap_do_cache[tpl] = true;
544  } else {
545  RTLIL::Module *constmapped_tpl = map->module(constmap_tpl_name(sigmap, tpl, cell, false));
546  if (constmapped_tpl != nullptr)
547  tpl = constmapped_tpl;
548  }
549 
550  if (techmap_do_cache.count(tpl) == 0)
551  {
552  bool keep_running = true;
553  techmap_do_cache[tpl] = true;
554 
555  std::set<std::string> techmap_wire_names;
556 
557  while (keep_running)
558  {
560  keep_running = false;
561 
562  for (auto &it : twd)
563  techmap_wire_names.insert(it.first);
564 
565  for (auto &it : twd["_TECHMAP_FAIL_"]) {
566  RTLIL::SigSpec value = it.value;
567  if (value.is_fully_const() && value.as_bool()) {
568  log("Not using module `%s' from techmap as it contains a %s marker wire with non-zero value %s.\n",
569  derived_name.c_str(), RTLIL::id2cstr(it.wire->name), log_signal(value));
570  techmap_do_cache[tpl] = false;
571  }
572  }
573 
574  if (!techmap_do_cache[tpl])
575  break;
576 
577  for (auto &it : twd)
578  {
579  if (it.first.substr(0, 12) != "_TECHMAP_DO_" || it.second.empty())
580  continue;
581 
582  auto &data = it.second.front();
583 
584  if (!data.value.is_fully_const())
585  log_error("Techmap yielded config wire %s with non-const value %s.\n", RTLIL::id2cstr(data.wire->name), log_signal(data.value));
586 
587  techmap_wire_names.erase(it.first);
588 
589  const char *p = data.wire->name.c_str();
590  const char *q = strrchr(p+1, '.');
591  q = q ? q : p+1;
592 
593  std::string cmd_string = data.value.as_const().decode_string();
594 
595  restart_eval_cmd_string:
596  if (cmd_string.rfind("CONSTMAP; ", 0) == 0)
597  {
598  cmd_string = cmd_string.substr(strlen("CONSTMAP; "));
599 
600  log("Analyzing pattern of constant bits for this cell:\n");
601  RTLIL::IdString new_tpl_name = constmap_tpl_name(sigmap, tpl, cell, true);
602  log("Creating constmapped module `%s'.\n", log_id(new_tpl_name));
603  log_assert(map->module(new_tpl_name) == nullptr);
604 
605  RTLIL::Module *new_tpl = map->addModule(new_tpl_name);
606  tpl->cloneInto(new_tpl);
607 
608  techmap_do_cache.erase(tpl);
609  techmap_do_cache[new_tpl] = true;
610  tpl = new_tpl;
611 
612  std::map<RTLIL::SigBit, RTLIL::SigBit> port_new2old_map;
613  std::map<RTLIL::SigBit, RTLIL::SigBit> port_connmap;
614  std::map<RTLIL::SigBit, RTLIL::SigBit> cellbits_to_tplbits;
615 
616  for (auto wire : tpl->wires().to_vector())
617  {
618  if (!wire->port_input || wire->port_output)
619  continue;
620 
621  RTLIL::IdString port_name = wire->name;
622  tpl->rename(wire, NEW_ID);
623 
624  RTLIL::Wire *new_wire = tpl->addWire(port_name, wire);
625  wire->port_input = false;
626  wire->port_id = 0;
627 
628  for (int i = 0; i < wire->width; i++) {
629  port_new2old_map[RTLIL::SigBit(new_wire, i)] = RTLIL::SigBit(wire, i);
630  port_connmap[RTLIL::SigBit(wire, i)] = RTLIL::SigBit(new_wire, i);
631  }
632  }
633 
634  for (auto conn : cell->connections())
635  for (int i = 0; i < GetSize(conn.second); i++)
636  {
637  RTLIL::SigBit bit = sigmap(conn.second[i]);
638  RTLIL::SigBit tplbit(tpl->wire(conn.first), i);
639 
640  if (bit.wire == nullptr)
641  {
642  RTLIL::SigBit oldbit = port_new2old_map.at(tplbit);
643  port_connmap.at(oldbit) = bit;
644  }
645  else if (cellbits_to_tplbits.count(bit))
646  {
647  RTLIL::SigBit oldbit = port_new2old_map.at(tplbit);
648  port_connmap.at(oldbit) = cellbits_to_tplbits[bit];
649  }
650  else
651  cellbits_to_tplbits[bit] = tplbit;
652  }
653 
654  RTLIL::SigSig port_conn;
655  for (auto &it : port_connmap) {
656  port_conn.first.append_bit(it.first);
657  port_conn.second.append_bit(it.second);
658  }
659  tpl->connect(port_conn);
660 
661  tpl->check();
662  goto restart_eval_cmd_string;
663  }
664 
665  if (cmd_string.rfind("RECURSION; ", 0) == 0)
666  {
667  cmd_string = cmd_string.substr(strlen("RECURSION; "));
668  while (techmap_module(map, tpl, map, handled_cells, celltypeMap, true)) { }
669  goto restart_eval_cmd_string;
670  }
671 
672  Pass::call_on_module(map, tpl, cmd_string);
673 
674  log_assert(!strncmp(q, "_TECHMAP_DO_", 12));
675  std::string new_name = data.wire->name.substr(0, q-p) + "_TECHMAP_DONE_" + data.wire->name.substr(q-p+12);
676  while (tpl->wires_.count(new_name))
677  new_name += "_";
678  tpl->rename(data.wire->name, new_name);
679 
680  keep_running = true;
681  break;
682  }
683  }
684 
686  for (auto &it : twd) {
687  if (it.first != "_TECHMAP_FAIL_" && it.first.substr(0, 12) != "_TECHMAP_DO_" && it.first.substr(0, 14) != "_TECHMAP_DONE_")
688  log_error("Techmap yielded unknown config wire %s.\n", it.first.c_str());
689  if (techmap_do_cache[tpl])
690  for (auto &it2 : it.second)
691  if (!it2.value.is_fully_const())
692  log_error("Techmap yielded config wire %s with non-const value %s.\n", RTLIL::id2cstr(it2.wire->name), log_signal(it2.value));
693  techmap_wire_names.erase(it.first);
694  }
695 
696  for (auto &it : techmap_wire_names)
697  log_error("Techmap special wire %s disappeared. This is considered a fatal error.\n", RTLIL::id2cstr(it));
698 
699  if (recursive_mode) {
700  if (log_continue) {
701  log_header("Continuing TECHMAP pass.\n");
702  log_continue = false;
703  }
704  while (techmap_module(map, tpl, map, handled_cells, celltypeMap, true)) { }
705  }
706  }
707 
708  if (techmap_do_cache.at(tpl) == false)
709  continue;
710 
711  if (log_continue) {
712  log_header("Continuing TECHMAP pass.\n");
713  log_continue = false;
714  }
715 
716  if (extern_mode && !in_recursion)
717  {
718  std::string m_name = stringf("$extern:%s", log_id(tpl));
719 
720  if (!design->module(m_name))
721  {
722  RTLIL::Module *m = design->addModule(m_name);
723  tpl->cloneInto(m);
724 
725  for (auto cell : m->cells()) {
726  if (cell->type.substr(0, 2) == "\\$")
727  cell->type = cell->type.substr(1);
728  }
729 
730  module_queue.insert(m);
731  }
732 
733  log("%s %s.%s to imported %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(m_name));
734  cell->type = m_name;
735  cell->parameters.clear();
736  }
737  else
738  {
739  log("%s %s.%s using %s.\n", mapmsg_prefix.c_str(), log_id(module), log_id(cell), log_id(tpl));
740  techmap_module_worker(design, module, cell, tpl);
741  cell = NULL;
742  }
743  did_something = true;
744  mapped_cell = true;
745  break;
746  }
747 
748  if (assert_mode && !mapped_cell)
749  log_error("(ASSERT MODE) Failed to map cell %s.%s (%s).\n", log_id(module), log_id(cell), log_id(cell->type));
750 
751  handled_cells.insert(cell);
752  }
753 
754  if (log_continue) {
755  log_header("Continuing TECHMAP pass.\n");
756  log_continue = false;
757  }
758 
759  return did_something;
760  }
761 };
762 
763 struct TechmapPass : public Pass {
764  TechmapPass() : Pass("techmap", "generic technology mapper") { }
765  virtual void help()
766  {
767  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
768  log("\n");
769  log(" techmap [-map filename] [selection]\n");
770  log("\n");
771  log("This pass implements a very simple technology mapper that replaces cells in\n");
772  log("the design with implementations given in form of a verilog or ilang source\n");
773  log("file.\n");
774  log("\n");
775  log(" -map filename\n");
776  log(" the library of cell implementations to be used.\n");
777  log(" without this parameter a builtin library is used that\n");
778  log(" transforms the internal RTL cells to the internal gate\n");
779  log(" library.\n");
780  log("\n");
781  log(" -map %%<design-name>\n");
782  log(" like -map above, but with an in-memory design instead of a file.\n");
783  log("\n");
784  log(" -share_map filename\n");
785  log(" like -map, but look for the file in the share directory (where the\n");
786  log(" yosys data files are). this is mainly used internally when techmap\n");
787  log(" is called from other commands.\n");
788  log("\n");
789  log(" -extern\n");
790  log(" load the cell implementations as separate modules into the design\n");
791  log(" instead of inlining them.\n");
792  log("\n");
793  log(" -max_iter <number>\n");
794  log(" only run the specified number of iterations.\n");
795  log("\n");
796  log(" -recursive\n");
797  log(" instead of the iterative breadth-first algorithm use a recursive\n");
798  log(" depth-first algorithm. both methods should yield equivialent results,\n");
799  log(" but may differ in performance.\n");
800  log("\n");
801  log(" -autoproc\n");
802  log(" Automatically call \"proc\" on implementations that contain processes.\n");
803  log("\n");
804  log(" -assert\n");
805  log(" this option will cause techmap to exit with an error if it can't map\n");
806  log(" a selected cell. only cell types that end on an underscore are accepted\n");
807  log(" as final cell types by this mode.\n");
808  log("\n");
809  log(" -D <define>, -I <incdir>\n");
810  log(" this options are passed as-is to the verilog frontend for loading the\n");
811  log(" map file. Note that the verilog frontend is also called with the\n");
812  log(" '-ignore_redef' option set.\n");
813  log("\n");
814  log("When a module in the map file has the 'techmap_celltype' attribute set, it will\n");
815  log("match cells with a type that match the text value of this attribute. Otherwise\n");
816  log("the module name will be used to match the cell.\n");
817  log("\n");
818  log("When a module in the map file has the 'techmap_simplemap' attribute set, techmap\n");
819  log("will use 'simplemap' (see 'help simplemap') to map cells matching the module.\n");
820  log("\n");
821  log("When a module in the map file has the 'techmap_maccmap' attribute set, techmap\n");
822  log("will use 'maccmap' (see 'help maccmap') to map cells matching the module.\n");
823  log("\n");
824  log("When a module in the map file has the 'techmap_wrap' attribute set, techmap\n");
825  log("will create a wrapper for the cell and then run the command string that the\n");
826  log("attribute is set to on the wrapper module.\n");
827  log("\n");
828  log("All wires in the modules from the map file matching the pattern _TECHMAP_*\n");
829  log("or *._TECHMAP_* are special wires that are used to pass instructions from\n");
830  log("the mapping module to the techmap command. At the moment the following special\n");
831  log("wires are supported:\n");
832  log("\n");
833  log(" _TECHMAP_FAIL_\n");
834  log(" When this wire is set to a non-zero constant value, techmap will not\n");
835  log(" use this module and instead try the next module with a matching\n");
836  log(" 'techmap_celltype' attribute.\n");
837  log("\n");
838  log(" When such a wire exists but does not have a constant value after all\n");
839  log(" _TECHMAP_DO_* commands have been executed, an error is generated.\n");
840  log("\n");
841  log(" _TECHMAP_DO_*\n");
842  log(" This wires are evaluated in alphabetical order. The constant text value\n");
843  log(" of this wire is a yosys command (or sequence of commands) that is run\n");
844  log(" by techmap on the module. A common use case is to run 'proc' on modules\n");
845  log(" that are written using always-statements.\n");
846  log("\n");
847  log(" When such a wire has a non-constant value at the time it is to be\n");
848  log(" evaluated, an error is produced. That means it is possible for such a\n");
849  log(" wire to start out as non-constant and evaluate to a constant value\n");
850  log(" during processing of other _TECHMAP_DO_* commands.\n");
851  log("\n");
852  log(" A _TECHMAP_DO_* command may start with the special token 'CONSTMAP; '.\n");
853  log(" in this case techmap will create a copy for each distinct configuration\n");
854  log(" of constant inputs and shorted inputs at this point and import the\n");
855  log(" constant and connected bits into the map module. All further commands\n");
856  log(" are executed in this copy. This is a very convenient way of creating\n");
857  log(" optimizied specializations of techmap modules without using the special\n");
858  log(" parameters described below.\n");
859  log("\n");
860  log(" A _TECHMAP_DO_* command may start with the special token 'RECURSION; '.\n");
861  log(" then techmap will recursively replace the cells in the module with their\n");
862  log(" implementation. This is not affected by the -max_iter option.\n");
863  log("\n");
864  log(" It is possible to combine both prefixes to 'RECURSION; CONSTMAP; '.\n");
865  log("\n");
866  log("In addition to this special wires, techmap also supports special parameters in\n");
867  log("modules in the map file:\n");
868  log("\n");
869  log(" _TECHMAP_CELLTYPE_\n");
870  log(" When a parameter with this name exists, it will be set to the type name\n");
871  log(" of the cell that matches the module.\n");
872  log("\n");
873  log(" _TECHMAP_CONSTMSK_<port-name>_\n");
874  log(" _TECHMAP_CONSTVAL_<port-name>_\n");
875  log(" When this pair of parameters is available in a module for a port, then\n");
876  log(" former has a 1-bit for each constant input bit and the latter has the\n");
877  log(" value for this bit. The unused bits of the latter are set to undef (x).\n");
878  log("\n");
879  log(" _TECHMAP_BITS_CONNMAP_\n");
880  log(" _TECHMAP_CONNMAP_<port-name>_\n");
881  log(" For an N-bit port, the _TECHMAP_CONNMAP_<port-name>_ parameter, if it\n");
882  log(" exists, will be set to an N*_TECHMAP_BITS_CONNMAP_ bit vector containing\n");
883  log(" N words (of _TECHMAP_BITS_CONNMAP_ bits each) that assign each single\n");
884  log(" bit driver a unique id. The values 0-3 are reserved for 0, 1, x, and z.\n");
885  log(" This can be used to detect shorted inputs.\n");
886  log("\n");
887  log("When a module in the map file has a parameter where the according cell in the\n");
888  log("design has a port, the module from the map file is only used if the port in\n");
889  log("the design is connected to a constant value. The parameter is then set to the\n");
890  log("constant value.\n");
891  log("\n");
892  log("A cell with the name _TECHMAP_REPLACE_ in the map file will inherit the name\n");
893  log("of the cell that is beeing replaced.\n");
894  log("\n");
895  log("See 'help extract' for a pass that does the opposite thing.\n");
896  log("\n");
897  log("See 'help flatten' for a pass that does flatten the design (which is\n");
898  log("esentially techmap but using the design itself as map library).\n");
899  log("\n");
900  }
901  virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
902  {
903  log_header("Executing TECHMAP pass (map to technology primitives).\n");
904  log_push();
905 
906  TechmapWorker worker;
908 
909  std::vector<std::string> map_files;
910  std::string verilog_frontend = "verilog -ignore_redef";
911  int max_iter = -1;
912 
913  size_t argidx;
914  for (argidx = 1; argidx < args.size(); argidx++) {
915  if (args[argidx] == "-map" && argidx+1 < args.size()) {
916  if (args[argidx+1].substr(0, 2) == "+/")
917  map_files.push_back(proc_share_dirname() + args[++argidx].substr(2));
918  else
919  map_files.push_back(args[++argidx]);
920  continue;
921  }
922  if (args[argidx] == "-share_map" && argidx+1 < args.size()) {
923  map_files.push_back(proc_share_dirname() + args[++argidx]);
924  continue;
925  }
926  if (args[argidx] == "-max_iter" && argidx+1 < args.size()) {
927  max_iter = atoi(args[++argidx].c_str());
928  continue;
929  }
930  if (args[argidx] == "-D" && argidx+1 < args.size()) {
931  verilog_frontend += " -D " + args[++argidx];
932  continue;
933  }
934  if (args[argidx] == "-I" && argidx+1 < args.size()) {
935  verilog_frontend += " -I " + args[++argidx];
936  continue;
937  }
938  if (args[argidx] == "-assert") {
939  worker.assert_mode = true;
940  continue;
941  }
942  if (args[argidx] == "-extern") {
943  worker.extern_mode = true;
944  continue;
945  }
946  if (args[argidx] == "-recursive") {
947  worker.recursive_mode = true;
948  continue;
949  }
950  if (args[argidx] == "-autoproc") {
951  worker.autoproc_mode = true;
952  continue;
953  }
954  break;
955  }
956  extra_args(args, argidx, design);
957 
958  RTLIL::Design *map = new RTLIL::Design;
959  if (map_files.empty()) {
960  std::istringstream f(stdcells_code);
961  Frontend::frontend_call(map, &f, "<techmap.v>", verilog_frontend);
962  } else
963  for (auto &fn : map_files)
964  if (fn.substr(0, 1) == "%") {
965  if (!saved_designs.count(fn.substr(1))) {
966  delete map;
967  log_cmd_error("Can't saved design `%s'.\n", fn.c_str()+1);
968  }
969  for (auto mod : saved_designs.at(fn.substr(1))->modules())
970  if (!map->has(mod->name))
971  map->add(mod->clone());
972  } else {
973  std::ifstream f;
974  f.open(fn.c_str());
975  if (f.fail())
976  log_cmd_error("Can't open map file `%s'\n", fn.c_str());
977  Frontend::frontend_call(map, &f, fn, (fn.size() > 3 && fn.substr(fn.size()-3) == ".il") ? "ilang" : verilog_frontend);
978  }
979 
980  std::map<RTLIL::IdString, RTLIL::Module*> modules_new;
981  for (auto &it : map->modules_) {
982  if (it.first.substr(0, 2) == "\\$")
983  it.second->name = it.first.substr(1);
984  modules_new[it.second->name] = it.second;
985  }
986  map->modules_.swap(modules_new);
987 
988  std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> celltypeMap;
989  for (auto &it : map->modules_) {
990  if (it.second->attributes.count("\\techmap_celltype") && !it.second->attributes.at("\\techmap_celltype").bits.empty()) {
991  char *p = strdup(it.second->attributes.at("\\techmap_celltype").decode_string().c_str());
992  for (char *q = strtok(p, " \t\r\n"); q; q = strtok(NULL, " \t\r\n"))
993  celltypeMap[RTLIL::escape_id(q)].insert(it.first);
994  free(p);
995  } else
996  celltypeMap[it.first].insert(it.first);
997  }
998 
999  for (auto module : design->modules())
1000  worker.module_queue.insert(module);
1001 
1002  while (!worker.module_queue.empty())
1003  {
1004  RTLIL::Module *module = *worker.module_queue.begin();
1005  worker.module_queue.erase(module);
1006 
1007  bool did_something = true;
1008  std::set<RTLIL::Cell*> handled_cells;
1009  while (did_something) {
1010  did_something = false;
1011  if (worker.techmap_module(design, module, map, handled_cells, celltypeMap, false))
1012  did_something = true;
1013  if (did_something)
1014  module->check();
1015  if (max_iter > 0 && --max_iter == 0)
1016  break;
1017  }
1018  }
1019 
1020  log("No more expansions possible.\n");
1021  delete map;
1022 
1023  log_pop();
1024  }
1025 } TechmapPass;
1026 
1027 struct FlattenPass : public Pass {
1028  FlattenPass() : Pass("flatten", "flatten design") { }
1029  virtual void help()
1030  {
1031  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
1032  log("\n");
1033  log(" flatten [selection]\n");
1034  log("\n");
1035  log("This pass flattens the design by replacing cells by their implementation. This\n");
1036  log("pass is very simmilar to the 'techmap' pass. The only difference is that this\n");
1037  log("pass is using the current design as mapping library.\n");
1038  log("\n");
1039  }
1040  virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
1041  {
1042  log_header("Executing FLATTEN pass (flatten design).\n");
1043  log_push();
1044 
1045  extra_args(args, 1, design);
1046 
1047  TechmapWorker worker;
1048  worker.flatten_mode = true;
1049 
1050  std::map<RTLIL::IdString, std::set<RTLIL::IdString, RTLIL::sort_by_id_str>> celltypeMap;
1051  for (auto &it : design->modules_)
1052  celltypeMap[it.first].insert(it.first);
1053 
1054  RTLIL::Module *top_mod = NULL;
1055  if (design->full_selection())
1056  for (auto mod : design->modules())
1057  if (mod->get_bool_attribute("\\top"))
1058  top_mod = mod;
1059 
1060  bool did_something = true;
1061  std::set<RTLIL::Cell*> handled_cells;
1062  while (did_something) {
1063  did_something = false;
1064  if (top_mod != NULL) {
1065  if (worker.techmap_module(design, top_mod, design, handled_cells, celltypeMap, false))
1066  did_something = true;
1067  } else {
1068  for (auto mod : design->modules())
1069  if (worker.techmap_module(design, mod, design, handled_cells, celltypeMap, false))
1070  did_something = true;
1071  }
1072  }
1073 
1074  log("No more expansions possible.\n");
1075 
1076  if (top_mod != NULL) {
1077  std::map<RTLIL::IdString, RTLIL::Module*> new_modules;
1078  for (auto mod : design->modules())
1079  if (mod == top_mod || mod->get_bool_attribute("\\blackbox")) {
1080  new_modules[mod->name] = mod;
1081  } else {
1082  log("Deleting now unused module %s.\n", log_id(mod));
1083  delete mod;
1084  }
1085  design->modules_.swap(new_modules);
1086  }
1087 
1088  log_pop();
1089  }
1090 } FlattenPass;
1091 
const char * c_str() const
Definition: rtlil.h:178
bool selected(T1 *module) const
Definition: rtlil.h:551
RTLIL::Wire * wire
Definition: rtlil.h:907
TechmapPass TechmapPass
void cloneInto(RTLIL::Module *new_mod) const
Definition: rtlil.cc:1022
bool recursive_mode
Definition: techmap.cc:82
std::string str() const
Definition: rtlil.h:182
YOSYS_NAMESPACE_END USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN void apply_prefix(std::string prefix, std::string &id)
Definition: techmap.cc:44
RTLIL::Wire * wire(RTLIL::IdString id)
Definition: rtlil.h:637
std::set< RTLIL::Module *, RTLIL::IdString::compare_ptr_by_name< RTLIL::Module > > module_queue
Definition: techmap.cc:70
std::string stringf(const char *fmt,...)
Definition: yosys.cc:58
RTLIL::State data
Definition: rtlil.h:909
bool sort()
Definition: utils.h:194
void free(void *)
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
Definition: rtlil.cc:1353
void add(RTLIL::Module *module)
Definition: rtlil.cc:259
void node(T n)
Definition: utils.h:145
void log_header(const char *format,...)
Definition: log.cc:188
const std::vector< RTLIL::SigSig > & connections() const
Definition: rtlil.cc:1307
void clear()
Definition: rtlil.h:223
#define YOSYS_NAMESPACE_END
Definition: yosys.h:100
RTLIL::Const as_const() const
Definition: rtlil.cc:2857
std::map< RTLIL::Module *, bool > techmap_do_cache
Definition: techmap.cc:69
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
Definition: rtlil.h:595
bool as_bool() const
Definition: rtlil.cc:2818
static std::string unescape_id(std::string str)
Definition: rtlil.h:257
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
Definition: log.cc:269
static void frontend_call(RTLIL::Design *design, std::istream *f, std::string filename, std::string command)
Definition: register.cc:375
RTLIL::IdString name
Definition: rtlil.h:853
std::map< std::pair< RTLIL::IdString, std::map< RTLIL::IdString, RTLIL::Const > >, RTLIL::Module * > techmap_cache
Definition: techmap.cc:68
bool port_input
Definition: rtlil.h:827
std::map< RTLIL::IdString, void(*)(RTLIL::Module *, RTLIL::Cell *)> simplemap_mappers
Definition: techmap.cc:67
std::map< RTLIL::IdString, RTLIL::Memory * > memories
Definition: rtlil.h:601
void log_error(const char *format,...)
Definition: log.cc:204
RTLIL::Module * module
Definition: abc.cc:94
std::set< RTLIL::IdString > avail_parameters
Definition: rtlil.h:600
int port_id
Definition: rtlil.h:826
RTLIL::IdString type
Definition: rtlil.h:854
void log_pop()
Definition: log.cc:237
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
Definition: techmap.cc:1040
void select(T1 *module, T2 *member)
Definition: rtlil.h:559
virtual void check()
Definition: rtlil.cc:948
virtual RTLIL::IdString derive(RTLIL::Design *design, std::map< RTLIL::IdString, RTLIL::Const > parameters)
Definition: rtlil.cc:467
YOSYS_NAMESPACE_BEGIN void simplemap_get_mappers(std::map< RTLIL::IdString, void(*)(RTLIL::Module *, RTLIL::Cell *)> &mappers)
Definition: simplemap.cc:403
void apply(RTLIL::SigBit &bit) const
Definition: sigtools.h:383
static std::string escape_id(std::string str)
Definition: rtlil.h:251
bool port_output
Definition: rtlil.h:827
bool flatten_mode
Definition: techmap.cc:81
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool did_something
Definition: opt_const.cc:32
std::map< std::string, RTLIL::Design * > saved_designs
Definition: design.cc:27
std::map< std::string, std::vector< TechmapWireData > > TechmapWires
Definition: techmap.cc:77
bool techmap_module(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Design *map, std::set< RTLIL::Cell * > &handled_cells, const std::map< RTLIL::IdString, std::set< RTLIL::IdString, RTLIL::sort_by_id_str >> &celltypeMap, bool in_recursion)
Definition: techmap.cc:271
void connect(const RTLIL::SigSig &conn)
Definition: rtlil.cc:1278
bool full_selection() const
Definition: rtlil.h:547
#define PRIVATE_NAMESPACE_BEGIN
Definition: yosys.h:97
void edge(T left, T right)
Definition: utils.h:151
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
RTLIL::SigSpecIterator begin()
Definition: rtlil.h:1024
void fixup_ports()
Definition: rtlil.cc:1312
#define log_assert(_assert_expr_)
Definition: log.h:85
bool is_fully_const() const
Definition: rtlil.cc:2763
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
Definition: rtlil.cc:1331
RTLIL::IdString name
Definition: rtlil.h:599
#define NEW_ID
Definition: yosys.h:166
bool assert_mode
Definition: techmap.cc:80
#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
void log_cmd_error(const char *format,...)
Definition: log.cc:211
void remove_const()
Definition: rtlil.cc:2464
RTLIL::Module * addModule(RTLIL::IdString name)
Definition: rtlil.cc:270
RTLIL::Module * module(RTLIL::IdString name)
Definition: rtlil.cc:254
std::map< RTLIL::IdString, RTLIL::Process * > processes
Definition: rtlil.h:602
std::string substr(size_t pos=0, size_t len=std::string::npos) const
Definition: rtlil.h:208
bool has(RTLIL::IdString id) const
Definition: rtlil.h:519
#define USING_YOSYS_NAMESPACE
Definition: yosys.h:102
RTLIL::ObjRange< RTLIL::Cell * > cells()
Definition: rtlil.h:641
RTLIL::ObjRange< RTLIL::Module * > modules()
Definition: rtlil.cc:249
std::map< RTLIL::IdString, RTLIL::Module * > modules_
Definition: rtlil.h:507
FlattenPass FlattenPass
RTLIL::Cell * cell(RTLIL::IdString id)
Definition: rtlil.h:638
#define NULL
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
Definition: rtlil.h:596
#define YOSYS_NAMESPACE_BEGIN
Definition: yosys.h:99
static void call_on_module(RTLIL::Design *design, RTLIL::Module *module, std::string command)
Definition: register.cc:240
void remove(const std::set< RTLIL::Wire * > &wires)
Definition: rtlil.cc:1158
void log(const char *format,...)
Definition: log.cc:180
std::vector< T > sorted
Definition: utils.h:137
std::string sha1(const std::string &string)
Definition: sha1.cpp:270
virtual void help()
Definition: techmap.cc:1029
bool extern_mode
Definition: techmap.cc:79
std::vector< RTLIL::State > bits
Definition: rtlil.h:438
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
Definition: techmap.cc:901
void log_push()
Definition: log.cc:232
virtual void help()
Definition: techmap.cc:765
std::string proc_share_dirname()
Definition: yosys.cc:543
void maccmap(RTLIL::Module *module, RTLIL::Cell *cell, bool unmap=false)
Definition: maccmap.cc:265
void add(RTLIL::SigSpec from, RTLIL::SigSpec to)
Definition: sigtools.h:347
std::map< RTLIL::IdString, RTLIL::SigSpec > connections_
Definition: rtlil.h:855
RTLIL::Design * design
Definition: rtlil.h:589
std::string id(RTLIL::IdString internal_id, bool may_rename=true)
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
Definition: register.cc:128
std::string constmap_tpl_name(SigMap &sigmap, RTLIL::Module *tpl, RTLIL::Cell *cell, bool verbose)
Definition: techmap.cc:94
std::pair< SigSpec, SigSpec > SigSig
Definition: rtlil.h:71
const std::map< RTLIL::IdString, RTLIL::SigSpec > & connections() const
Definition: rtlil.cc:1814
void techmap_module_worker(RTLIL::Design *design, RTLIL::Module *module, RTLIL::Cell *cell, RTLIL::Module *tpl)
Definition: techmap.cc:156
const char * log_id(RTLIL::IdString str)
Definition: log.cc:283
RTLIL::SigSpecIterator end()
Definition: rtlil.h:1025
YOSYS_NAMESPACE_BEGIN int autoidx
Definition: yosys.cc:51
void rename(RTLIL::Wire *wire, RTLIL::IdString new_name)
Definition: rtlil.cc:1185
bool autoproc_mode
Definition: techmap.cc:83
TechmapWires techmap_find_special_wires(RTLIL::Module *module)
Definition: techmap.cc:121