yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
dfflibmap.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/log.h"
22 #include "libparse.h"
23 #include <string.h>
24 #include <errno.h>
25 
28 
29 struct cell_mapping {
30  std::string cell_name;
31  std::map<std::string, char> ports;
32 };
33 static std::map<RTLIL::IdString, cell_mapping> cell_mappings;
34 
35 static void logmap(std::string dff)
36 {
37  if (cell_mappings.count(dff) == 0) {
38  log(" unmapped dff cell: %s\n", dff.c_str());
39  } else {
40  log(" %s %s (", cell_mappings[dff].cell_name.c_str(), dff.substr(1).c_str());
41  bool first = true;
42  for (auto &port : cell_mappings[dff].ports) {
43  char arg[3] = { port.second, 0, 0 };
44  if ('a' <= arg[0] && arg[0] <= 'z')
45  arg[1] = arg[0] - ('a' - 'A'), arg[0] = '~';
46  else
47  arg[1] = arg[0], arg[0] = ' ';
48  log("%s.%s(%s)", first ? "" : ", ", port.first.c_str(), arg);
49  first = false;
50  }
51  log(");\n");
52  }
53 }
54 
55 static void logmap_all()
56 {
57  logmap("$_DFF_N_");
58  logmap("$_DFF_P_");
59 
60  logmap("$_DFF_NN0_");
61  logmap("$_DFF_NN1_");
62  logmap("$_DFF_NP0_");
63  logmap("$_DFF_NP1_");
64  logmap("$_DFF_PN0_");
65  logmap("$_DFF_PN1_");
66  logmap("$_DFF_PP0_");
67  logmap("$_DFF_PP1_");
68 
69  logmap("$_DFFSR_NNN_");
70  logmap("$_DFFSR_NNP_");
71  logmap("$_DFFSR_NPN_");
72  logmap("$_DFFSR_NPP_");
73  logmap("$_DFFSR_PNN_");
74  logmap("$_DFFSR_PNP_");
75  logmap("$_DFFSR_PPN_");
76  logmap("$_DFFSR_PPP_");
77 }
78 
79 static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol)
80 {
81  if (cell == NULL || attr == NULL || attr->value.empty())
82  return false;
83 
84  std::string value = attr->value;
85 
86  for (size_t pos = value.find_first_of("\" \t()"); pos != std::string::npos; pos = value.find_first_of("\" \t()"))
87  value.erase(pos, 1);
88 
89  if (value[value.size()-1] == '\'') {
90  pin_name = value.substr(0, value.size()-1);
91  pin_pol = false;
92  } else if (value[0] == '!') {
93  pin_name = value.substr(1, value.size()-1);
94  pin_pol = false;
95  } else {
96  pin_name = value;
97  pin_pol = true;
98  }
99 
100  for (auto child : cell->children)
101  if (child->id == "pin" && child->args.size() == 1 && child->args[0] == pin_name)
102  return true;
103  return false;
104 }
105 
106 static void find_cell(LibertyAst *ast, std::string cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval)
107 {
108  LibertyAst *best_cell = NULL;
109  std::map<std::string, char> best_cell_ports;
110  int best_cell_pins = 0;
111  double best_cell_area = 0;
112 
113  if (ast->id != "library")
114  log_error("Format error in liberty file.\n");
115 
116  for (auto cell : ast->children)
117  {
118  if (cell->id != "cell" || cell->args.size() != 1)
119  continue;
120 
121  LibertyAst *ff = cell->find("ff");
122  if (ff == NULL)
123  continue;
124 
125  std::string cell_clk_pin, cell_rst_pin, cell_next_pin;
126  bool cell_clk_pol, cell_rst_pol, cell_next_pol;
127 
128  if (!parse_pin(cell, ff->find("clocked_on"), cell_clk_pin, cell_clk_pol) || cell_clk_pol != clkpol)
129  continue;
130  if (!parse_pin(cell, ff->find("next_state"), cell_next_pin, cell_next_pol))
131  continue;
132  if (has_reset && rstval == false) {
133  if (!parse_pin(cell, ff->find("clear"), cell_rst_pin, cell_rst_pol) || cell_rst_pol != rstpol)
134  continue;
135  }
136  if (has_reset && rstval == true) {
137  if (!parse_pin(cell, ff->find("preset"), cell_rst_pin, cell_rst_pol) || cell_rst_pol != rstpol)
138  continue;
139  }
140 
141  std::map<std::string, char> this_cell_ports;
142  this_cell_ports[cell_clk_pin] = 'C';
143  if (has_reset)
144  this_cell_ports[cell_rst_pin] = 'R';
145  this_cell_ports[cell_next_pin] = 'D';
146 
147  double area = 0;
148  LibertyAst *ar = cell->find("area");
149  if (ar != NULL && !ar->value.empty())
150  area = atof(ar->value.c_str());
151 
152  int num_pins = 0;
153  bool found_output = false;
154  for (auto pin : cell->children)
155  {
156  if (pin->id != "pin" || pin->args.size() != 1)
157  continue;
158 
159  LibertyAst *dir = pin->find("direction");
160  if (dir == NULL || dir->value == "internal")
161  continue;
162  num_pins++;
163 
164  if (dir->value == "input" && this_cell_ports.count(pin->args[0]) == 0)
165  goto continue_cell_loop;
166 
167  LibertyAst *func = pin->find("function");
168  if (dir->value == "output" && func != NULL) {
169  std::string value = func->value;
170  for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t"))
171  value.erase(pos, 1);
172  if ((cell_next_pol == true && value == ff->args[0]) || (cell_next_pol == false && value == ff->args[1])) {
173  this_cell_ports[pin->args[0]] = 'Q';
174  found_output = true;
175  }
176  }
177 
178  if (this_cell_ports.count(pin->args[0]) == 0)
179  this_cell_ports[pin->args[0]] = 0;
180  }
181 
182  if (!found_output || (best_cell != NULL && num_pins > best_cell_pins))
183  continue;
184 
185  if (best_cell != NULL && num_pins == best_cell_pins && area > best_cell_area)
186  continue;
187 
188  best_cell = cell;
189  best_cell_pins = num_pins;
190  best_cell_area = area;
191  best_cell_ports.swap(this_cell_ports);
192  continue_cell_loop:;
193  }
194 
195  if (best_cell != NULL) {
196  log(" cell %s (pins=%d, area=%.2f) is a direct match for cell type %s.\n", best_cell->args[0].c_str(), best_cell_pins, best_cell_area, cell_type.substr(1).c_str());
197  cell_mappings[cell_type].cell_name = best_cell->args[0];
198  cell_mappings[cell_type].ports = best_cell_ports;
199  }
200 }
201 
202 static void find_cell_sr(LibertyAst *ast, std::string cell_type, bool clkpol, bool setpol, bool clrpol)
203 {
204  LibertyAst *best_cell = NULL;
205  std::map<std::string, char> best_cell_ports;
206  int best_cell_pins = 0;
207  double best_cell_area = 0;
208 
209  if (ast->id != "library")
210  log_error("Format error in liberty file.\n");
211 
212  for (auto cell : ast->children)
213  {
214  if (cell->id != "cell" || cell->args.size() != 1)
215  continue;
216 
217  LibertyAst *ff = cell->find("ff");
218  if (ff == NULL)
219  continue;
220 
221  std::string cell_clk_pin, cell_set_pin, cell_clr_pin, cell_next_pin;
222  bool cell_clk_pol, cell_set_pol, cell_clr_pol, cell_next_pol;
223 
224  if (!parse_pin(cell, ff->find("clocked_on"), cell_clk_pin, cell_clk_pol) || cell_clk_pol != clkpol)
225  continue;
226  if (!parse_pin(cell, ff->find("next_state"), cell_next_pin, cell_next_pol))
227  continue;
228  if (!parse_pin(cell, ff->find("preset"), cell_set_pin, cell_set_pol) || cell_set_pol != setpol)
229  continue;
230  if (!parse_pin(cell, ff->find("clear"), cell_clr_pin, cell_clr_pol) || cell_clr_pol != clrpol)
231  continue;
232 
233  std::map<std::string, char> this_cell_ports;
234  this_cell_ports[cell_clk_pin] = 'C';
235  this_cell_ports[cell_set_pin] = 'S';
236  this_cell_ports[cell_clr_pin] = 'R';
237  this_cell_ports[cell_next_pin] = 'D';
238 
239  double area = 0;
240  LibertyAst *ar = cell->find("area");
241  if (ar != NULL && !ar->value.empty())
242  area = atof(ar->value.c_str());
243 
244  int num_pins = 0;
245  bool found_output = false;
246  for (auto pin : cell->children)
247  {
248  if (pin->id != "pin" || pin->args.size() != 1)
249  continue;
250 
251  LibertyAst *dir = pin->find("direction");
252  if (dir == NULL || dir->value == "internal")
253  continue;
254  num_pins++;
255 
256  if (dir->value == "input" && this_cell_ports.count(pin->args[0]) == 0)
257  goto continue_cell_loop;
258 
259  LibertyAst *func = pin->find("function");
260  if (dir->value == "output" && func != NULL) {
261  std::string value = func->value;
262  for (size_t pos = value.find_first_of("\" \t"); pos != std::string::npos; pos = value.find_first_of("\" \t"))
263  value.erase(pos, 1);
264  if ((cell_next_pol == true && value == ff->args[0]) || (cell_next_pol == false && value == ff->args[1])) {
265  this_cell_ports[pin->args[0]] = 'Q';
266  found_output = true;
267  }
268  }
269 
270  if (this_cell_ports.count(pin->args[0]) == 0)
271  this_cell_ports[pin->args[0]] = 0;
272  }
273 
274  if (!found_output || (best_cell != NULL && num_pins > best_cell_pins))
275  continue;
276 
277  if (best_cell != NULL && num_pins == best_cell_pins && area > best_cell_area)
278  continue;
279 
280  best_cell = cell;
281  best_cell_pins = num_pins;
282  best_cell_area = area;
283  best_cell_ports.swap(this_cell_ports);
284  continue_cell_loop:;
285  }
286 
287  if (best_cell != NULL) {
288  log(" cell %s (pins=%d, area=%.2f) is a direct match for cell type %s.\n", best_cell->args[0].c_str(), best_cell_pins, best_cell_area, cell_type.substr(1).c_str());
289  cell_mappings[cell_type].cell_name = best_cell->args[0];
290  cell_mappings[cell_type].ports = best_cell_ports;
291  }
292 }
293 
294 static bool expand_cellmap_worker(std::string from, std::string to, std::string inv)
295 {
296  if (cell_mappings.count(to) > 0)
297  return false;
298 
299  log(" create mapping for %s from mapping for %s.\n", to.c_str(), from.c_str());
300  cell_mappings[to].cell_name = cell_mappings[from].cell_name;
301  cell_mappings[to].ports = cell_mappings[from].ports;
302 
303  for (auto &it : cell_mappings[to].ports) {
304  char cmp_ch = it.second;
305  if ('a' <= cmp_ch && cmp_ch <= 'z')
306  cmp_ch -= 'a' - 'A';
307  if (inv.find(cmp_ch) == std::string::npos)
308  continue;
309  if ('a' <= it.second && it.second <= 'z')
310  it.second -= 'a' - 'A';
311  else if ('A' <= it.second && it.second <= 'Z')
312  it.second += 'a' - 'A';
313  }
314  return true;
315 }
316 
317 static bool expand_cellmap(std::string pattern, std::string inv)
318 {
319  std::vector<std::pair<std::string, std::string>> from_to_list;
320  bool return_status = false;
321 
322  for (auto &it : cell_mappings) {
323  std::string from = it.first.str(), to = it.first.str();
324  if (from.size() != pattern.size())
325  continue;
326  for (size_t i = 0; i < from.size(); i++) {
327  if (pattern[i] == '*') {
328  to[i] = from[i] == 'P' ? 'N' :
329  from[i] == 'N' ? 'P' :
330  from[i] == '1' ? '0' :
331  from[i] == '0' ? '1' : '*';
332  } else
333  if (pattern[i] != '?' && pattern[i] != from[i])
334  goto pattern_failed;
335  }
336  from_to_list.push_back(std::pair<std::string, std::string>(from, to));
337  pattern_failed:;
338  }
339 
340  for (auto &it : from_to_list)
341  return_status = return_status || expand_cellmap_worker(it.first, it.second, inv);
342  return return_status;
343 }
344 
345 static void map_sr_to_arst(const char *from, const char *to)
346 {
347  if (!cell_mappings.count(from) || cell_mappings.count(to) > 0)
348  return;
349 
350  char from_clk_pol = from[8], from_set_pol = from[9], from_clr_pol = from[10];
351  char to_clk_pol = to[6], to_rst_pol = to[7], to_rst_val = to[8];
352 
353  log_assert(from_clk_pol == to_clk_pol);
354  log_assert(to_rst_pol == from_set_pol && to_rst_pol == from_clr_pol);
355 
356  log(" create mapping for %s from mapping for %s.\n", to, from);
357  cell_mappings[to].cell_name = cell_mappings[from].cell_name;
358  cell_mappings[to].ports = cell_mappings[from].ports;
359 
360  for (auto &it : cell_mappings[to].ports)
361  {
362  bool is_set_pin = it.second == 'S' || it.second == 's';
363  bool is_clr_pin = it.second == 'R' || it.second == 'r';
364 
365  if (!is_set_pin && !is_clr_pin)
366  continue;
367 
368  if ((to_rst_val == '0' && is_set_pin) || (to_rst_val == '1' && is_clr_pin))
369  {
370  // this is the unused set/clr pin -- deactivate it
371  if (is_set_pin)
372  it.second = (from_set_pol == 'P') == (it.second == 'S') ? '0' : '1';
373  else
374  it.second = (from_clr_pol == 'P') == (it.second == 'R') ? '0' : '1';
375  }
376  else
377  {
378  // this is the used set/clr pin -- rename it to 'reset'
379  if (it.second == 'S')
380  it.second = 'R';
381  if (it.second == 's')
382  it.second = 'r';
383  }
384  }
385 }
386 
388 {
389  log("Mapping DFF cells in module `%s':\n", module->name.c_str());
390 
391  std::vector<RTLIL::Cell*> cell_list;
392  for (auto &it : module->cells_) {
393  if (design->selected(module, it.second) && cell_mappings.count(it.second->type) > 0)
394  cell_list.push_back(it.second);
395  }
396 
397  std::map<std::string, int> stats;
398  for (auto cell : cell_list)
399  {
400  auto cell_type = cell->type;
401  auto cell_name = cell->name;
402  auto cell_connections = cell->connections();
403  module->remove(cell);
404 
405  cell_mapping &cm = cell_mappings[cell_type];
406  RTLIL::Cell *new_cell = module->addCell(cell_name, "\\" + cm.cell_name);
407 
408  for (auto &port : cm.ports) {
409  RTLIL::SigSpec sig;
410  if ('A' <= port.second && port.second <= 'Z') {
411  sig = cell_connections[std::string("\\") + port.second];
412  } else
413  if (port.second == 'q') {
414  RTLIL::SigSpec old_sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))];
415  sig = module->addWire(NEW_ID, GetSize(old_sig));
416  module->addNotGate(NEW_ID, sig, old_sig);
417  } else
418  if ('a' <= port.second && port.second <= 'z') {
419  sig = cell_connections[std::string("\\") + char(port.second - ('a' - 'A'))];
420  sig = module->NotGate(NEW_ID, sig);
421  } else
422  if (port.second == '0' || port.second == '1') {
423  sig = RTLIL::SigSpec(port.second == '0' ? 0 : 1, 1);
424  } else
425  if (port.second != 0)
426  log_abort();
427  new_cell->setPort("\\" + port.first, sig);
428  }
429 
430  stats[stringf(" mapped %%d %s cells to %s cells.\n", cell_type.c_str(), new_cell->type.c_str())]++;
431  }
432 
433  for (auto &stat: stats)
434  log(stat.first.c_str(), stat.second);
435 }
436 
437 struct DfflibmapPass : public Pass {
438  DfflibmapPass() : Pass("dfflibmap", "technology mapping of flip-flops") { }
439  virtual void help()
440  {
441  log("\n");
442  log(" dfflibmap -liberty <file> [selection]\n");
443  log("\n");
444  log("Map internal flip-flop cells to the flip-flop cells in the technology\n");
445  log("library specified in the given liberty file.\n");
446  log("\n");
447  log("This pass may add inverters as needed. Therefore it is recommended to\n");
448  log("first run this pass and then map the logic paths to the target technology.\n");
449  log("\n");
450  }
451  virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
452  {
453  log_header("Executing DFFLIBMAP pass (mapping DFF cells to sequential cells from liberty file).\n");
454 
455  std::string liberty_file;
456 
457  size_t argidx;
458  for (argidx = 1; argidx < args.size(); argidx++)
459  {
460  std::string arg = args[argidx];
461  if (arg == "-liberty" && argidx+1 < args.size()) {
462  liberty_file = args[++argidx];
463  continue;
464  }
465  break;
466  }
467  extra_args(args, argidx, design);
468 
469  if (liberty_file.empty())
470  log_cmd_error("Missing `-liberty liberty_file' option!\n");
471 
472  std::ifstream f;
473  f.open(liberty_file.c_str());
474  if (f.fail())
475  log_cmd_error("Can't open liberty file `%s': %s\n", liberty_file.c_str(), strerror(errno));
476  LibertyParser libparser(f);
477  f.close();
478 
479  find_cell(libparser.ast, "$_DFF_N_", false, false, false, false);
480  find_cell(libparser.ast, "$_DFF_P_", true, false, false, false);
481 
482  find_cell(libparser.ast, "$_DFF_NN0_", false, true, false, false);
483  find_cell(libparser.ast, "$_DFF_NN1_", false, true, false, true);
484  find_cell(libparser.ast, "$_DFF_NP0_", false, true, true, false);
485  find_cell(libparser.ast, "$_DFF_NP1_", false, true, true, true);
486  find_cell(libparser.ast, "$_DFF_PN0_", true, true, false, false);
487  find_cell(libparser.ast, "$_DFF_PN1_", true, true, false, true);
488  find_cell(libparser.ast, "$_DFF_PP0_", true, true, true, false);
489  find_cell(libparser.ast, "$_DFF_PP1_", true, true, true, true);
490 
491  find_cell_sr(libparser.ast, "$_DFFSR_NNN_", false, false, false);
492  find_cell_sr(libparser.ast, "$_DFFSR_NNP_", false, false, true);
493  find_cell_sr(libparser.ast, "$_DFFSR_NPN_", false, true, false);
494  find_cell_sr(libparser.ast, "$_DFFSR_NPP_", false, true, true);
495  find_cell_sr(libparser.ast, "$_DFFSR_PNN_", true, false, false);
496  find_cell_sr(libparser.ast, "$_DFFSR_PNP_", true, false, true);
497  find_cell_sr(libparser.ast, "$_DFFSR_PPN_", true, true, false);
498  find_cell_sr(libparser.ast, "$_DFFSR_PPP_", true, true, true);
499 
500  // try to implement as many cells as possible just by inverting
501  // the SET and RESET pins. If necessary, implement cell types
502  // by inverting both D and Q. Only invert clock pins if there
503  // is no other way of implementing the cell.
504  while (1)
505  {
506  if (expand_cellmap("$_DFF_?*?_", "R") ||
507  expand_cellmap("$_DFFSR_?*?_", "S") ||
508  expand_cellmap("$_DFFSR_??*_", "R"))
509  continue;
510 
511  if (expand_cellmap("$_DFF_??*_", "DQ"))
512  continue;
513 
514  if (expand_cellmap("$_DFF_*_", "C") ||
515  expand_cellmap("$_DFF_*??_", "C") ||
516  expand_cellmap("$_DFFSR_*??_", "C"))
517  continue;
518 
519  break;
520  }
521 
522  map_sr_to_arst("$_DFFSR_NNN_", "$_DFF_NN0_");
523  map_sr_to_arst("$_DFFSR_NNN_", "$_DFF_NN1_");
524  map_sr_to_arst("$_DFFSR_NPP_", "$_DFF_NP0_");
525  map_sr_to_arst("$_DFFSR_NPP_", "$_DFF_NP1_");
526  map_sr_to_arst("$_DFFSR_PNN_", "$_DFF_PN0_");
527  map_sr_to_arst("$_DFFSR_PNN_", "$_DFF_PN1_");
528  map_sr_to_arst("$_DFFSR_PPP_", "$_DFF_PP0_");
529  map_sr_to_arst("$_DFFSR_PPP_", "$_DFF_PP1_");
530 
531  log(" final dff cell mappings:\n");
532  logmap_all();
533 
534  for (auto &it : design->modules_)
535  if (design->selected(it.second) && !it.second->get_bool_attribute("\\blackbox"))
536  dfflibmap(design, it.second);
537 
538  cell_mappings.clear();
539  }
540 } DfflibmapPass;
541 
const char * c_str() const
Definition: rtlil.h:178
bool selected(T1 *module) const
Definition: rtlil.h:551
static std::map< RTLIL::IdString, cell_mapping > cell_mappings
Definition: dfflibmap.cc:33
virtual void help()
Definition: dfflibmap.cc:439
std::map< std::string, char > ports
Definition: dfflibmap.cc:31
std::string stringf(const char *fmt,...)
Definition: yosys.cc:58
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
Definition: rtlil.cc:1353
void log_header(const char *format,...)
Definition: log.cc:188
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
Definition: rtlil.cc:1789
void log_error(const char *format,...)
Definition: log.cc:204
RTLIL::Module * module
Definition: abc.cc:94
RTLIL::IdString type
Definition: rtlil.h:854
static void logmap_all()
Definition: dfflibmap.cc:55
#define log_abort()
Definition: log.h:84
RTLIL::Cell * addNotGate(RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_y)
static void find_cell(LibertyAst *ast, std::string cell_type, bool clkpol, bool has_reset, bool rstpol, bool rstval)
Definition: dfflibmap.cc:106
static void find_cell_sr(LibertyAst *ast, std::string cell_type, bool clkpol, bool setpol, bool clrpol)
Definition: dfflibmap.cc:202
#define PRIVATE_NAMESPACE_BEGIN
Definition: yosys.h:97
int GetSize(RTLIL::Wire *wire)
Definition: yosys.cc:334
#define log_assert(_assert_expr_)
Definition: log.h:85
std::string cell_name
Definition: dfflibmap.cc:30
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
static void logmap(std::string dff)
Definition: dfflibmap.cc:35
#define PRIVATE_NAMESPACE_END
Definition: yosys.h:98
Definition: register.h:27
RTLIL::SigBit NotGate(RTLIL::IdString name, RTLIL::SigBit sig_a)
void log_cmd_error(const char *format,...)
Definition: log.cc:211
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
Definition: dfflibmap.cc:451
static bool expand_cellmap(std::string pattern, std::string inv)
Definition: dfflibmap.cc:317
#define USING_YOSYS_NAMESPACE
Definition: yosys.h:102
static bool expand_cellmap_worker(std::string from, std::string to, std::string inv)
Definition: dfflibmap.cc:294
std::map< RTLIL::IdString, RTLIL::Module * > modules_
Definition: rtlil.h:507
static void map_sr_to_arst(const char *from, const char *to)
Definition: dfflibmap.cc:345
DfflibmapPass DfflibmapPass
#define NULL
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
Definition: rtlil.h:596
void remove(const std::set< RTLIL::Wire * > &wires)
Definition: rtlil.cc:1158
void log(const char *format,...)
Definition: log.cc:180
static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module)
Definition: dfflibmap.cc:387
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
Definition: register.cc:128
static bool parse_pin(LibertyAst *cell, LibertyAst *attr, std::string &pin_name, bool &pin_pol)
Definition: dfflibmap.cc:79