yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
liberty.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 
21 #include "kernel/register.h"
22 #include "kernel/log.h"
23 
25 
26 struct token_t {
27  char type;
29  token_t (char t) : type(t) { }
30  token_t (char t, RTLIL::SigSpec s) : type(t), sig(s) { }
31 };
32 
34 {
35  log_assert(*expr != 0);
36 
37  int id_len = 0;
38  while (('a' <= expr[id_len] && expr[id_len] <= 'z') || ('A' <= expr[id_len] && expr[id_len] <= 'Z') ||
39  ('0' <= expr[id_len] && expr[id_len] <= '9') || expr[id_len] == '.' || expr[id_len] == '_') id_len++;
40 
41  if (id_len == 0)
42  log_error("Expected identifier at `%s'.\n", expr);
43 
44  if (id_len == 1 && (*expr == '0' || *expr == '1'))
45  return *(expr++) == '0' ? RTLIL::State::S0 : RTLIL::State::S1;
46 
47  std::string id = RTLIL::escape_id(std::string(expr, id_len));
48  if (!module->wires_.count(id))
49  log_error("Can't resolve wire name %s.\n", RTLIL::unescape_id(id).c_str());
50 
51  expr += id_len;
52  return module->wires_.at(id);
53 }
54 
56 {
57  RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_");
58  cell->setPort("\\A", A);
59  cell->setPort("\\Y", module->addWire(NEW_ID));
60  return cell->getPort("\\Y");
61 }
62 
64 {
65  RTLIL::Cell *cell = module->addCell(NEW_ID, "$_XOR_");
66  cell->setPort("\\A", A);
67  cell->setPort("\\B", B);
68  cell->setPort("\\Y", module->addWire(NEW_ID));
69  return cell->getPort("\\Y");
70 }
71 
73 {
74  RTLIL::Cell *cell = module->addCell(NEW_ID, "$_AND_");
75  cell->setPort("\\A", A);
76  cell->setPort("\\B", B);
77  cell->setPort("\\Y", module->addWire(NEW_ID));
78  return cell->getPort("\\Y");
79 }
80 
82 {
83  RTLIL::Cell *cell = module->addCell(NEW_ID, "$_OR_");
84  cell->setPort("\\A", A);
85  cell->setPort("\\B", B);
86  cell->setPort("\\Y", module->addWire(NEW_ID));
87  return cell->getPort("\\Y");
88 }
89 
90 static bool parse_func_reduce(RTLIL::Module *module, std::vector<token_t> &stack, token_t next_token)
91 {
92  int top = int(stack.size())-1;
93 
94  if (0 <= top-1 && stack[top].type == 0 && stack[top-1].type == '!') {
95  token_t t = token_t(0, create_inv_cell(module, stack[top].sig));
96  stack.pop_back();
97  stack.pop_back();
98  stack.push_back(t);
99  return true;
100  }
101 
102  if (0 <= top-1 && stack[top].type == '\'' && stack[top-1].type == 0) {
103  token_t t = token_t(0, create_inv_cell(module, stack[top-1].sig));
104  stack.pop_back();
105  stack.pop_back();
106  stack.push_back(t);
107  return true;
108  }
109 
110  if (0 <= top && stack[top].type == 0) {
111  if (next_token.type == '\'')
112  return false;
113  stack[top].type = 1;
114  return true;
115  }
116 
117  if (0 <= top-2 && stack[top-2].type == 1 && stack[top-1].type == '^' && stack[top].type == 1) {
118  token_t t = token_t(1, create_xor_cell(module, stack[top-2].sig, stack[top].sig));
119  stack.pop_back();
120  stack.pop_back();
121  stack.pop_back();
122  stack.push_back(t);
123  return true;
124  }
125 
126  if (0 <= top && stack[top].type == 1) {
127  if (next_token.type == '^')
128  return false;
129  stack[top].type = 2;
130  return true;
131  }
132 
133  if (0 <= top-1 && stack[top-1].type == 2 && stack[top].type == 2) {
134  token_t t = token_t(2, create_and_cell(module, stack[top-1].sig, stack[top].sig));
135  stack.pop_back();
136  stack.pop_back();
137  stack.push_back(t);
138  return true;
139  }
140 
141  if (0 <= top-2 && stack[top-2].type == 2 && (stack[top-1].type == '*' || stack[top-1].type == '&') && stack[top].type == 2) {
142  token_t t = token_t(2, create_and_cell(module, stack[top-2].sig, stack[top].sig));
143  stack.pop_back();
144  stack.pop_back();
145  stack.pop_back();
146  stack.push_back(t);
147  return true;
148  }
149 
150  if (0 <= top && stack[top].type == 2) {
151  if (next_token.type == '*' || next_token.type == '&' || next_token.type == 0 || next_token.type == '(')
152  return false;
153  stack[top].type = 3;
154  return true;
155  }
156 
157  if (0 <= top-2 && stack[top-2].type == 3 && (stack[top-1].type == '+' || stack[top-1].type == '|') && stack[top].type == 3) {
158  token_t t = token_t(3, create_or_cell(module, stack[top-2].sig, stack[top].sig));
159  stack.pop_back();
160  stack.pop_back();
161  stack.pop_back();
162  stack.push_back(t);
163  return true;
164  }
165 
166  if (0 <= top-2 && stack[top-2].type == '(' && stack[top-1].type == 3 && stack[top].type == ')') {
167  token_t t = token_t(0, stack[top-1].sig);
168  stack.pop_back();
169  stack.pop_back();
170  stack.pop_back();
171  stack.push_back(t);
172  return true;
173  }
174 
175  return false;
176 }
177 
179 {
180  const char *orig_expr = expr;
181  std::vector<token_t> stack;
182 
183  while (*expr)
184  {
185  if (*expr == ' ' || *expr == '\t' || *expr == '\r' || *expr == '\n' || *expr == '"') {
186  expr++;
187  continue;
188  }
189 
190  token_t next_token(0);
191  if (*expr == '(' || *expr == ')' || *expr == '\'' || *expr == '!' || *expr == '^' || *expr == '*' || *expr == '+' || *expr == '|')
192  next_token = token_t(*(expr++));
193  else
194  next_token = token_t(0, parse_func_identifier(module, expr));
195 
196  while (parse_func_reduce(module, stack, next_token)) {}
197  stack.push_back(next_token);
198  }
199 
200  while (parse_func_reduce(module, stack, token_t('.'))) {}
201 
202 #if 0
203  for (size_t i = 0; i < stack.size(); i++)
204  if (stack[i].type < 16)
205  log("%3d: %d %s\n", int(i), stack[i].type, log_signal(stack[i].sig));
206  else
207  log("%3d: %c\n", int(i), stack[i].type);
208 #endif
209 
210  if (stack.size() != 1 || stack.back().type != 3)
211  log_error("Parser error in function expr `%s'.\n", orig_expr);
212 
213  return stack.back().sig;
214 }
215 
216 static void create_ff(RTLIL::Module *module, LibertyAst *node)
217 {
218  RTLIL::SigSpec iq_sig(module->addWire(RTLIL::escape_id(node->args.at(0))));
219  RTLIL::SigSpec iqn_sig(module->addWire(RTLIL::escape_id(node->args.at(1))));
220 
221  RTLIL::SigSpec clk_sig, data_sig, clear_sig, preset_sig;
222  bool clk_polarity = true, clear_polarity = true, preset_polarity = true;
223 
224  for (auto child : node->children) {
225  if (child->id == "clocked_on")
226  clk_sig = parse_func_expr(module, child->value.c_str());
227  if (child->id == "next_state")
228  data_sig = parse_func_expr(module, child->value.c_str());
229  if (child->id == "clear")
230  clear_sig = parse_func_expr(module, child->value.c_str());
231  if (child->id == "preset")
232  preset_sig = parse_func_expr(module, child->value.c_str());
233  }
234 
235  if (clk_sig.size() == 0 || data_sig.size() == 0)
236  log_error("FF cell %s has no next_state and/or clocked_on attribute.\n", log_id(module->name));
237 
238  for (bool rerun_invert_rollback = true; rerun_invert_rollback;)
239  {
240  rerun_invert_rollback = false;
241 
242  for (auto &it : module->cells_) {
243  if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clk_sig) {
244  clk_sig = it.second->getPort("\\A");
245  clk_polarity = !clk_polarity;
246  rerun_invert_rollback = true;
247  }
248  if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clear_sig) {
249  clear_sig = it.second->getPort("\\A");
250  clear_polarity = !clear_polarity;
251  rerun_invert_rollback = true;
252  }
253  if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == preset_sig) {
254  preset_sig = it.second->getPort("\\A");
255  preset_polarity = !preset_polarity;
256  rerun_invert_rollback = true;
257  }
258  }
259  }
260 
261  RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_");
262  cell->setPort("\\A", iq_sig);
263  cell->setPort("\\Y", iqn_sig);
264 
265  cell = module->addCell(NEW_ID, "");
266  cell->setPort("\\D", data_sig);
267  cell->setPort("\\Q", iq_sig);
268  cell->setPort("\\C", clk_sig);
269 
270  if (clear_sig.size() == 0 && preset_sig.size() == 0) {
271  cell->type = stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N');
272  }
273 
274  if (clear_sig.size() == 1 && preset_sig.size() == 0) {
275  cell->type = stringf("$_DFF_%c%c0_", clk_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N');
276  cell->setPort("\\R", clear_sig);
277  }
278 
279  if (clear_sig.size() == 0 && preset_sig.size() == 1) {
280  cell->type = stringf("$_DFF_%c%c1_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N');
281  cell->setPort("\\R", preset_sig);
282  }
283 
284  if (clear_sig.size() == 1 && preset_sig.size() == 1) {
285  cell->type = stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', preset_polarity ? 'P' : 'N', clear_polarity ? 'P' : 'N');
286  cell->setPort("\\S", preset_sig);
287  cell->setPort("\\R", clear_sig);
288  }
289 
290  log_assert(!cell->type.empty());
291 }
292 
293 static void create_latch(RTLIL::Module *module, LibertyAst *node)
294 {
295  RTLIL::SigSpec iq_sig(module->addWire(RTLIL::escape_id(node->args.at(0))));
296  RTLIL::SigSpec iqn_sig(module->addWire(RTLIL::escape_id(node->args.at(1))));
297 
298  RTLIL::SigSpec enable_sig, data_sig, clear_sig, preset_sig;
299  bool enable_polarity = true, clear_polarity = true, preset_polarity = true;
300 
301  for (auto child : node->children) {
302  if (child->id == "enable")
303  enable_sig = parse_func_expr(module, child->value.c_str());
304  if (child->id == "data_in")
305  data_sig = parse_func_expr(module, child->value.c_str());
306  if (child->id == "clear")
307  clear_sig = parse_func_expr(module, child->value.c_str());
308  if (child->id == "preset")
309  preset_sig = parse_func_expr(module, child->value.c_str());
310  }
311 
312  if (enable_sig.size() == 0 || data_sig.size() == 0)
313  log_error("Latch cell %s has no data_in and/or enable attribute.\n", log_id(module->name));
314 
315  for (bool rerun_invert_rollback = true; rerun_invert_rollback;)
316  {
317  rerun_invert_rollback = false;
318 
319  for (auto &it : module->cells_) {
320  if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == enable_sig) {
321  enable_sig = it.second->getPort("\\A");
322  enable_polarity = !enable_polarity;
323  rerun_invert_rollback = true;
324  }
325  if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == clear_sig) {
326  clear_sig = it.second->getPort("\\A");
327  clear_polarity = !clear_polarity;
328  rerun_invert_rollback = true;
329  }
330  if (it.second->type == "$_NOT_" && it.second->getPort("\\Y") == preset_sig) {
331  preset_sig = it.second->getPort("\\A");
332  preset_polarity = !preset_polarity;
333  rerun_invert_rollback = true;
334  }
335  }
336  }
337 
338  RTLIL::Cell *cell = module->addCell(NEW_ID, "$_NOT_");
339  cell->setPort("\\A", iq_sig);
340  cell->setPort("\\Y", iqn_sig);
341 
342  if (clear_sig.size() == 1)
343  {
344  RTLIL::SigSpec clear_negative = clear_sig;
345  RTLIL::SigSpec clear_enable = clear_sig;
346 
347  if (clear_polarity == true || clear_polarity != enable_polarity)
348  {
349  RTLIL::Cell *inv = module->addCell(NEW_ID, "$_NOT_");
350  inv->setPort("\\A", clear_sig);
351  inv->setPort("\\Y", module->addWire(NEW_ID));
352 
353  if (clear_polarity == true)
354  clear_negative = inv->getPort("\\Y");
355  if (clear_polarity != enable_polarity)
356  clear_enable = inv->getPort("\\Y");
357  }
358 
359  RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_AND_");
360  data_gate->setPort("\\A", data_sig);
361  data_gate->setPort("\\B", clear_negative);
362  data_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID));
363 
364  RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_");
365  enable_gate->setPort("\\A", enable_sig);
366  enable_gate->setPort("\\B", clear_enable);
367  enable_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID));
368  }
369 
370  if (preset_sig.size() == 1)
371  {
372  RTLIL::SigSpec preset_positive = preset_sig;
373  RTLIL::SigSpec preset_enable = preset_sig;
374 
375  if (preset_polarity == false || preset_polarity != enable_polarity)
376  {
377  RTLIL::Cell *inv = module->addCell(NEW_ID, "$_NOT_");
378  inv->setPort("\\A", preset_sig);
379  inv->setPort("\\Y", module->addWire(NEW_ID));
380 
381  if (preset_polarity == false)
382  preset_positive = inv->getPort("\\Y");
383  if (preset_polarity != enable_polarity)
384  preset_enable = inv->getPort("\\Y");
385  }
386 
387  RTLIL::Cell *data_gate = module->addCell(NEW_ID, "$_OR_");
388  data_gate->setPort("\\A", data_sig);
389  data_gate->setPort("\\B", preset_positive);
390  data_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID));
391 
392  RTLIL::Cell *enable_gate = module->addCell(NEW_ID, enable_polarity ? "$_OR_" : "$_AND_");
393  enable_gate->setPort("\\A", enable_sig);
394  enable_gate->setPort("\\B", preset_enable);
395  enable_gate->setPort("\\Y", data_sig = module->addWire(NEW_ID));
396  }
397 
398  cell = module->addCell(NEW_ID, stringf("$_DLATCH_%c_", enable_polarity ? 'P' : 'N'));
399  cell->setPort("\\D", data_sig);
400  cell->setPort("\\Q", iq_sig);
401  cell->setPort("\\E", enable_sig);
402 }
403 
404 struct LibertyFrontend : public Frontend {
405  LibertyFrontend() : Frontend("liberty", "read cells from liberty file") { }
406  virtual void help()
407  {
408  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
409  log("\n");
410  log(" read_liberty [filename]\n");
411  log("\n");
412  log("Read cells from liberty file as modules into current design.\n");
413  log("\n");
414  log(" -lib\n");
415  log(" only create empty blackbox modules\n");
416  log("\n");
417  log(" -ignore_redef\n");
418  log(" ignore re-definitions of modules. (the default behavior is to\n");
419  log(" create an error message.)\n");
420  log("\n");
421  log(" -ignore_miss_func\n");
422  log(" ignore cells with missing function specification of outputs\n");
423  log("\n");
424  log(" -ignore_miss_dir\n");
425  log(" ignore cells with a missing or invalid direction\n");
426  log(" specification on a pin\n");
427  log("\n");
428  log(" -setattr <attribute_name>\n");
429  log(" set the specified attribute (to the value 1) on all loaded modules\n");
430  log("\n");
431  }
432  virtual void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
433  {
434  bool flag_lib = false;
435  bool flag_ignore_redef = false;
436  bool flag_ignore_miss_func = false;
437  bool flag_ignore_miss_dir = false;
438  std::vector<std::string> attributes;
439 
440  log_header("Executing Liberty frontend.\n");
441 
442  size_t argidx;
443  for (argidx = 1; argidx < args.size(); argidx++) {
444  std::string arg = args[argidx];
445  if (arg == "-lib") {
446  flag_lib = true;
447  continue;
448  }
449  if (arg == "-ignore_redef") {
450  flag_ignore_redef = true;
451  continue;
452  }
453  if (arg == "-ignore_miss_func") {
454  flag_ignore_miss_func = true;
455  continue;
456  }
457  if (arg == "-ignore_miss_dir") {
458  flag_ignore_miss_dir = true;
459  continue;
460  }
461  if (arg == "-setattr" && argidx+1 < args.size()) {
462  attributes.push_back(RTLIL::escape_id(args[++argidx]));
463  continue;
464  }
465  break;
466  }
467  extra_args(f, filename, args, argidx);
468 
469  LibertyParser parser(*f);
470  int cell_count = 0;
471 
472  for (auto cell : parser.ast->children)
473  {
474  if (cell->id != "cell" || cell->args.size() != 1)
475  continue;
476 
477  std::string cell_name = RTLIL::escape_id(cell->args.at(0));
478 
479  if (design->has(cell_name)) {
480  if (flag_ignore_redef)
481  continue;
482  log_error("Duplicate definition of cell/module %s.\n", RTLIL::unescape_id(cell_name).c_str());
483  }
484 
485  // log("Processing cell type %s.\n", RTLIL::unescape_id(cell_name).c_str());
486 
488  module->name = cell_name;
489 
490  if (flag_lib)
491  module->set_bool_attribute("\\blackbox");
492 
493  for (auto &attr : attributes)
494  module->attributes[attr] = 1;
495 
496  for (auto node : cell->children)
497  if (node->id == "pin" && node->args.size() == 1) {
498  LibertyAst *dir = node->find("direction");
499  if (!dir || (dir->value != "input" && dir->value != "output" && dir->value != "inout" && dir->value != "internal"))
500  {
501  if (!flag_ignore_miss_dir)
502  {
503  log_error("Missing or invalid direction for pin %s of cell %s.\n", node->args.at(0).c_str(), log_id(module->name));
504  } else {
505  log("Ignoring cell %s with missing or invalid direction for pin %s.\n", log_id(module->name), node->args.at(0).c_str());
506  delete module;
507  goto skip_cell;
508  }
509  }
510  if (!flag_lib || dir->value != "internal")
511  module->addWire(RTLIL::escape_id(node->args.at(0)));
512  }
513 
514  for (auto node : cell->children)
515  {
516  if (!flag_lib) {
517  if (node->id == "ff" && node->args.size() == 2)
518  create_ff(module, node);
519  if (node->id == "latch" && node->args.size() == 2)
520  create_latch(module, node);
521  }
522 
523  if (node->id == "pin" && node->args.size() == 1)
524  {
525  LibertyAst *dir = node->find("direction");
526 
527  if (flag_lib && dir->value == "internal")
528  continue;
529 
530  RTLIL::Wire *wire = module->wires_.at(RTLIL::escape_id(node->args.at(0)));
531 
532  if (dir && dir->value == "inout") {
533  wire->port_input = true;
534  wire->port_output = true;
535  }
536 
537  if (dir && dir->value == "input") {
538  wire->port_input = true;
539  continue;
540  }
541 
542  if (dir && dir->value == "output")
543  wire->port_output = true;
544 
545  if (flag_lib)
546  continue;
547 
548  LibertyAst *func = node->find("function");
549  if (func == NULL)
550  {
551  if (!flag_ignore_miss_func)
552  {
553  log_error("Missing function on output %s of cell %s.\n", log_id(wire->name), log_id(module->name));
554  } else {
555  log("Ignoring cell %s with missing function on output %s.\n", log_id(module->name), log_id(wire->name));
556  delete module;
557  goto skip_cell;
558  }
559  }
560 
561  RTLIL::SigSpec out_sig = parse_func_expr(module, func->value.c_str());
562  module->connect(RTLIL::SigSig(wire, out_sig));
563  }
564  }
565 
566  module->fixup_ports();
567  design->add(module);
568  cell_count++;
569 skip_cell:;
570  }
571 
572  log("Imported %d cell types from liberty file.\n", cell_count);
573  }
575 
577 
static std::string next_token(bool pass_newline=false)
Definition: preproc.cc:96
bool flag_lib
Definition: ast.cc:56
std::string stringf(const char *fmt,...)
Definition: yosys.cc:58
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
Definition: rtlil.cc:1353
void add(RTLIL::Module *module)
Definition: rtlil.cc:259
RTLIL::SigSpec sig
Definition: liberty.cc:28
bool clk_polarity
Definition: abc.cc:98
void log_header(const char *format,...)
Definition: log.cc:188
#define YOSYS_NAMESPACE_END
Definition: yosys.h:100
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
Definition: rtlil.h:595
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
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
Definition: rtlil.cc:1789
bool port_input
Definition: rtlil.h:827
token_t(char t, RTLIL::SigSpec s)
Definition: liberty.cc:30
char type
Definition: liberty.cc:27
static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *&expr)
Definition: liberty.cc:33
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 RTLIL::SigSpec create_and_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
Definition: liberty.cc:72
static void create_latch(RTLIL::Module *module, LibertyAst *node)
Definition: liberty.cc:293
static void create_ff(RTLIL::Module *module, LibertyAst *node)
Definition: liberty.cc:216
LibertyFrontend LibertyFrontend
bool empty() const
Definition: rtlil.h:219
static std::string escape_id(std::string str)
Definition: rtlil.h:251
bool port_output
Definition: rtlil.h:827
token_t(char t)
Definition: liberty.cc:29
void connect(const RTLIL::SigSig &conn)
Definition: rtlil.cc:1278
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
Definition: rtlil.cc:1809
static RTLIL::SigSpec create_inv_cell(RTLIL::Module *module, RTLIL::SigSpec A)
Definition: liberty.cc:55
static RTLIL::SigSpec parse_func_expr(RTLIL::Module *module, const char *expr)
Definition: liberty.cc:178
void fixup_ports()
Definition: rtlil.cc:1312
#define log_assert(_assert_expr_)
Definition: log.h:85
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
RTLIL::SigSpec clk_sig
Definition: abc.cc:99
RTLIL::IdString name
Definition: rtlil.h:825
bool has(RTLIL::IdString id) const
Definition: rtlil.h:519
#define NULL
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
Definition: rtlil.h:596
#define YOSYS_NAMESPACE_BEGIN
Definition: yosys.h:99
void log(const char *format,...)
Definition: log.cc:180
virtual void execute(std::istream *&f, std::string filename, std::vector< std::string > args, RTLIL::Design *design)
Definition: liberty.cc:432
static RTLIL::SigSpec create_or_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
Definition: liberty.cc:81
static bool parse_func_reduce(RTLIL::Module *module, std::vector< token_t > &stack, token_t next_token)
Definition: liberty.cc:90
static RTLIL::SigSpec create_xor_cell(RTLIL::Module *module, RTLIL::SigSpec A, RTLIL::SigSpec B)
Definition: liberty.cc:63
std::pair< SigSpec, SigSpec > SigSig
Definition: rtlil.h:71
const char * log_id(RTLIL::IdString str)
Definition: log.cc:283
virtual void help()
Definition: liberty.cc:406
void extra_args(std::istream *&f, std::string &filename, std::vector< std::string > args, size_t argidx)
Definition: register.cc:302