10c7fc85bf8212809885240b1cfe5ba22825dd30
[yosys.git] / frontends / ast / ast.cc
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 * This is the AST frontend library.
21 *
22 * The AST frontend library is not a frontend on it's own but provides a
23 * generic abstract syntax tree (AST) abstraction for HDL code and can be
24 * used by HDL frontends. See "ast.h" for an overview of the API and the
25 * Verilog frontend for an usage example.
26 *
27 */
28
29 #include "kernel/log.h"
30 #include "libs/sha1/sha1.h"
31 #include "ast.h"
32
33 #include <sstream>
34 #include <stdarg.h>
35 #include <assert.h>
36
37 using namespace AST;
38 using namespace AST_INTERNAL;
39
40 // instanciate global variables (public API)
41 namespace AST {
42 std::string current_filename;
43 void (*set_line_num)(int) = NULL;
44 int (*get_line_num)() = NULL;
45 }
46
47 // instanciate global variables (private API)
48 namespace AST_INTERNAL {
49 bool flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt;
50 AstNode *current_ast, *current_ast_mod;
51 std::map<std::string, AstNode*> current_scope;
52 RTLIL::SigSpec *genRTLIL_subst_from = NULL;
53 RTLIL::SigSpec *genRTLIL_subst_to = NULL;
54 RTLIL::SigSpec ignoreThisSignalsInInitial;
55 AstNode *current_top_block, *current_block, *current_block_child;
56 AstModule *current_module;
57 }
58
59 // convert node types to string
60 std::string AST::type2str(AstNodeType type)
61 {
62 switch (type)
63 {
64 #define X(_item) case _item: return #_item;
65 X(AST_NONE)
66 X(AST_DESIGN)
67 X(AST_MODULE)
68 X(AST_TASK)
69 X(AST_FUNCTION)
70 X(AST_WIRE)
71 X(AST_MEMORY)
72 X(AST_AUTOWIRE)
73 X(AST_PARAMETER)
74 X(AST_LOCALPARAM)
75 X(AST_DEFPARAM)
76 X(AST_PARASET)
77 X(AST_ARGUMENT)
78 X(AST_RANGE)
79 X(AST_CONSTANT)
80 X(AST_CELLTYPE)
81 X(AST_IDENTIFIER)
82 X(AST_PREFIX)
83 X(AST_FCALL)
84 X(AST_TO_SIGNED)
85 X(AST_TO_UNSIGNED)
86 X(AST_CONCAT)
87 X(AST_REPLICATE)
88 X(AST_BIT_NOT)
89 X(AST_BIT_AND)
90 X(AST_BIT_OR)
91 X(AST_BIT_XOR)
92 X(AST_BIT_XNOR)
93 X(AST_REDUCE_AND)
94 X(AST_REDUCE_OR)
95 X(AST_REDUCE_XOR)
96 X(AST_REDUCE_XNOR)
97 X(AST_REDUCE_BOOL)
98 X(AST_SHIFT_LEFT)
99 X(AST_SHIFT_RIGHT)
100 X(AST_SHIFT_SLEFT)
101 X(AST_SHIFT_SRIGHT)
102 X(AST_LT)
103 X(AST_LE)
104 X(AST_EQ)
105 X(AST_NE)
106 X(AST_GE)
107 X(AST_GT)
108 X(AST_ADD)
109 X(AST_SUB)
110 X(AST_MUL)
111 X(AST_DIV)
112 X(AST_MOD)
113 X(AST_POW)
114 X(AST_POS)
115 X(AST_NEG)
116 X(AST_LOGIC_AND)
117 X(AST_LOGIC_OR)
118 X(AST_LOGIC_NOT)
119 X(AST_TERNARY)
120 X(AST_MEMRD)
121 X(AST_MEMWR)
122 X(AST_TCALL)
123 X(AST_ASSIGN)
124 X(AST_CELL)
125 X(AST_PRIMITIVE)
126 X(AST_ALWAYS)
127 X(AST_INITIAL)
128 X(AST_BLOCK)
129 X(AST_ASSIGN_EQ)
130 X(AST_ASSIGN_LE)
131 X(AST_CASE)
132 X(AST_COND)
133 X(AST_DEFAULT)
134 X(AST_FOR)
135 X(AST_GENVAR)
136 X(AST_GENFOR)
137 X(AST_GENIF)
138 X(AST_GENCASE)
139 X(AST_GENBLOCK)
140 X(AST_POSEDGE)
141 X(AST_NEGEDGE)
142 X(AST_EDGE)
143 #undef X
144 default:
145 log_abort();
146 }
147 }
148
149 // check if attribute exists and has non-zero value
150 bool AstNode::get_bool_attribute(RTLIL::IdString id)
151 {
152 if (attributes.count(id) == 0)
153 return false;
154
155 AstNode *attr = attributes.at(id);
156 if (attr->type != AST_CONSTANT)
157 log_error("Attribute `%s' with non-constant value at %s:%d!\n",
158 id.c_str(), attr->filename.c_str(), attr->linenum);
159
160 return attr->integer != 0;
161 }
162
163 // create new node (AstNode constructor)
164 // (the optional child arguments make it easier to create AST trees)
165 AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2)
166 {
167 this->type = type;
168 filename = current_filename;
169 linenum = get_line_num();
170 is_input = false;
171 is_output = false;
172 is_reg = false;
173 is_signed = false;
174 range_valid = false;
175 port_id = 0;
176 range_left = -1;
177 range_right = 0;
178 integer = 0;
179 id2ast = NULL;
180
181 if (child1)
182 children.push_back(child1);
183 if (child2)
184 children.push_back(child2);
185 }
186
187 // create a (deep recursive) copy of a node
188 AstNode *AstNode::clone()
189 {
190 AstNode *that = new AstNode;
191 *that = *this;
192 for (auto &it : that->children)
193 it = it->clone();
194 for (auto &it : that->attributes)
195 it.second = it.second->clone();
196 return that;
197 }
198
199 // create a (deep recursive) copy of a node use 'other' as target root node
200 void AstNode::cloneInto(AstNode *other)
201 {
202 AstNode *tmp = clone();
203 other->delete_children();
204 *other = *tmp;
205 tmp->children.clear();
206 tmp->attributes.clear();
207 delete tmp;
208 }
209
210 // delete all children in this node
211 void AstNode::delete_children()
212 {
213 for (auto &it : children)
214 delete it;
215 children.clear();
216
217 for (auto &it : attributes)
218 delete it.second;
219 attributes.clear();
220 }
221
222 // AstNode destructor
223 AstNode::~AstNode()
224 {
225 delete_children();
226 }
227
228 // create a nice text representation of the node
229 // (traverse tree by recursion, use 'other' pointer for diffing two AST trees)
230 void AstNode::dumpAst(FILE *f, std::string indent)
231 {
232 if (f == NULL) {
233 for (auto f : log_files)
234 dumpAst(f, indent);
235 return;
236 }
237
238 std::string type_name = type2str(type);
239 fprintf(f, "%s%s <%s:%d>", indent.c_str(), type_name.c_str(), filename.c_str(), linenum);
240 if (!str.empty())
241 fprintf(f, " str='%s'", str.c_str());
242 if (!bits.empty()) {
243 fprintf(f, " bits='");
244 for (size_t i = bits.size(); i > 0; i--)
245 fprintf(f, "%c", bits[i-1] == RTLIL::S0 ? '0' :
246 bits[i-1] == RTLIL::S1 ? '1' :
247 bits[i-1] == RTLIL::Sx ? 'x' :
248 bits[i-1] == RTLIL::Sz ? 'z' : '?');
249 fprintf(f, "'(%zd)", bits.size());
250 }
251 if (is_input)
252 fprintf(f, " input");
253 if (is_output)
254 fprintf(f, " output");
255 if (is_reg)
256 fprintf(f, " reg");
257 if (is_signed)
258 fprintf(f, " signed");
259 if (port_id > 0)
260 fprintf(f, " port=%d", port_id);
261 if (range_valid || range_left != -1 || range_right != 0)
262 fprintf(f, " range=[%d:%d]%s", range_left, range_right, range_valid ? "" : "!");
263 if (integer != 0)
264 fprintf(f, " int=%u", (int)integer);
265 fprintf(f, "\n");
266
267 for (auto &it : attributes) {
268 fprintf(f, "%s ATTR %s:\n", indent.c_str(), it.first.c_str());
269 it.second->dumpAst(f, indent + " ");
270 }
271
272 for (size_t i = 0; i < children.size(); i++)
273 children[i]->dumpAst(f, indent + " ");
274 }
275
276 // helper function for AstNode::dumpVlog()
277 static std::string id2vl(std::string txt)
278 {
279 if (txt.size() > 1 && txt[0] == '\\')
280 txt = txt.substr(1);
281 for (size_t i = 0; i < txt.size(); i++) {
282 if ('A' <= txt[i] && txt[i] <= 'Z') continue;
283 if ('a' <= txt[i] && txt[i] <= 'z') continue;
284 if ('0' <= txt[i] && txt[i] <= '9') continue;
285 if (txt[i] == '_') continue;
286 txt = "\\" + txt + " ";
287 break;
288 }
289 return txt;
290 }
291
292 // dump AST node as verilog pseudo-code
293 void AstNode::dumpVlog(FILE *f, std::string indent)
294 {
295 bool first = true;
296 std::string txt;
297 std::vector<AstNode*> rem_children1, rem_children2;
298
299 if (f == NULL) {
300 for (auto f : log_files)
301 dumpVlog(f, indent);
302 return;
303 }
304
305 for (auto &it : attributes) {
306 fprintf(f, "%s" "(* %s = ", indent.c_str(), id2vl(it.first).c_str());
307 it.second->dumpVlog(f, "");
308 fprintf(f, " *)%s", indent.empty() ? "" : "\n");
309 }
310
311 switch (type)
312 {
313 case AST_MODULE:
314 fprintf(f, "%s" "module %s(", indent.c_str(), id2vl(str).c_str());
315 for (auto child : children)
316 if (child->type == AST_WIRE && (child->is_input || child->is_output)) {
317 fprintf(f, "%s%s", first ? "" : ", ", id2vl(child->str).c_str());
318 first = false;
319 }
320 fprintf(f, ");\n");
321
322 for (auto child : children)
323 if (child->type == AST_PARAMETER || child->type == AST_LOCALPARAM || child->type == AST_DEFPARAM)
324 child->dumpVlog(f, indent + " ");
325 else
326 rem_children1.push_back(child);
327
328 for (auto child : rem_children1)
329 if (child->type == AST_WIRE || child->type == AST_AUTOWIRE || child->type == AST_MEMORY)
330 child->dumpVlog(f, indent + " ");
331 else
332 rem_children2.push_back(child);
333 rem_children1.clear();
334
335 for (auto child : rem_children2)
336 if (child->type == AST_TASK || child->type == AST_FUNCTION)
337 child->dumpVlog(f, indent + " ");
338 else
339 rem_children1.push_back(child);
340 rem_children2.clear();
341
342 for (auto child : rem_children1)
343 child->dumpVlog(f, indent + " ");
344 rem_children1.clear();
345
346 fprintf(f, "%s" "endmodule\n", indent.c_str());
347 break;
348
349 case AST_WIRE:
350 if (is_input && is_output)
351 fprintf(f, "%s" "inout", indent.c_str());
352 else if (is_input)
353 fprintf(f, "%s" "input", indent.c_str());
354 else if (is_output)
355 fprintf(f, "%s" "output", indent.c_str());
356 else if (!is_reg)
357 fprintf(f, "%s" "wire", indent.c_str());
358 if (is_reg)
359 fprintf(f, "%s" "reg", (is_input || is_output) ? " " : indent.c_str());
360 if (is_signed)
361 fprintf(f, " signed");
362 for (auto child : children) {
363 fprintf(f, " ");
364 child->dumpVlog(f, "");
365 }
366 fprintf(f, " %s", id2vl(str).c_str());
367 fprintf(f, ";\n");
368 break;
369
370 case AST_MEMORY:
371 fprintf(f, "%s" "memory", indent.c_str());
372 if (is_signed)
373 fprintf(f, " signed");
374 for (auto child : children) {
375 fprintf(f, " ");
376 child->dumpVlog(f, "");
377 if (first)
378 fprintf(f, " %s", id2vl(str).c_str());
379 first = false;
380 }
381 fprintf(f, ";\n");
382 break;
383
384 case AST_RANGE:
385 if (range_valid)
386 fprintf(f, "[%d:%d]", range_left, range_right);
387 else {
388 for (auto child : children) {
389 fprintf(f, "%c", first ? '[' : ':');
390 child->dumpVlog(f, "");
391 first = false;
392 }
393 fprintf(f, "]");
394 }
395 break;
396
397 case AST_ALWAYS:
398 fprintf(f, "%s" "always @(", indent.c_str());
399 for (auto child : children) {
400 if (child->type != AST_POSEDGE && child->type != AST_NEGEDGE && child->type != AST_EDGE)
401 continue;
402 if (!first)
403 fprintf(f, ", ");
404 child->dumpVlog(f, "");
405 first = false;
406 }
407 fprintf(f, ")\n");
408 for (auto child : children) {
409 if (child->type != AST_POSEDGE && child->type != AST_NEGEDGE && child->type != AST_EDGE)
410 child->dumpVlog(f, indent + " ");
411 }
412 break;
413
414 case AST_INITIAL:
415 fprintf(f, "%s" "initial\n", indent.c_str());
416 for (auto child : children) {
417 if (child->type != AST_POSEDGE && child->type != AST_NEGEDGE && child->type != AST_EDGE)
418 child->dumpVlog(f, indent + " ");
419 }
420 break;
421
422 case AST_POSEDGE:
423 case AST_NEGEDGE:
424 case AST_EDGE:
425 if (type == AST_POSEDGE)
426 fprintf(f, "posedge ");
427 if (type == AST_NEGEDGE)
428 fprintf(f, "negedge ");
429 for (auto child : children)
430 child->dumpVlog(f, "");
431 break;
432
433 case AST_IDENTIFIER:
434 fprintf(f, "%s", id2vl(str).c_str());
435 for (auto child : children)
436 child->dumpVlog(f, "");
437 break;
438
439 case AST_CONSTANT:
440 if (!str.empty())
441 fprintf(f, "\"%s\"", str.c_str());
442 else if (bits.size() == 32)
443 fprintf(f, "%d", RTLIL::Const(bits).as_int());
444 else
445 fprintf(f, "%zd'b %s", bits.size(), RTLIL::Const(bits).as_string().c_str());
446 break;
447
448 case AST_BLOCK:
449 if (children.size() == 1) {
450 children[0]->dumpVlog(f, indent);
451 } else {
452 fprintf(f, "%s" "begin\n", indent.c_str());
453 for (auto child : children)
454 child->dumpVlog(f, indent + " ");
455 fprintf(f, "%s" "end\n", indent.c_str());
456 }
457 break;
458
459 case AST_CASE:
460 fprintf(f, "%s" "case (", indent.c_str());
461 children[0]->dumpVlog(f, "");
462 fprintf(f, ")\n");
463 for (size_t i = 1; i < children.size(); i++) {
464 AstNode *child = children[i];
465 child->dumpVlog(f, indent + " ");
466 }
467 fprintf(f, "%s" "endcase\n", indent.c_str());
468 break;
469
470 case AST_COND:
471 for (auto child : children) {
472 if (child->type == AST_BLOCK) {
473 fprintf(f, ":\n");
474 child->dumpVlog(f, indent + " ");
475 first = true;
476 } else {
477 fprintf(f, "%s", first ? indent.c_str() : ", ");
478 if (child->type == AST_DEFAULT)
479 fprintf(f, "default");
480 else
481 child->dumpVlog(f, "");
482 first = false;
483 }
484 }
485 break;
486
487 case AST_ASSIGN_EQ:
488 case AST_ASSIGN_LE:
489 fprintf(f, "%s", indent.c_str());
490 children[0]->dumpVlog(f, "");
491 fprintf(f, " %s ", type == AST_ASSIGN_EQ ? "=" : "<=");
492 children[1]->dumpVlog(f, "");
493 fprintf(f, ";\n");
494 break;
495
496 case AST_CONCAT:
497 fprintf(f, "{");
498 for (auto child : children) {
499 if (!first)
500 fprintf(f, ", ");
501 child->dumpVlog(f, "");
502 first = false;
503 }
504 fprintf(f, "}");
505 break;
506
507 case AST_REPLICATE:
508 fprintf(f, "{");
509 children[0]->dumpVlog(f, "");
510 fprintf(f, "{");
511 children[1]->dumpVlog(f, "");
512 fprintf(f, "}}");
513 break;
514
515 if (0) { case AST_BIT_NOT: txt = "~"; }
516 if (0) { case AST_REDUCE_AND: txt = "&"; }
517 if (0) { case AST_REDUCE_OR: txt = "|"; }
518 if (0) { case AST_REDUCE_XOR: txt = "^"; }
519 if (0) { case AST_REDUCE_XNOR: txt = "~^"; }
520 if (0) { case AST_REDUCE_BOOL: txt = "|"; }
521 if (0) { case AST_POS: txt = "+"; }
522 if (0) { case AST_NEG: txt = "-"; }
523 if (0) { case AST_LOGIC_NOT: txt = "!"; }
524 fprintf(f, "%s(", txt.c_str());
525 children[0]->dumpVlog(f, "");
526 fprintf(f, ")");
527 break;
528
529 if (0) { case AST_BIT_AND: txt = "&"; }
530 if (0) { case AST_BIT_OR: txt = "|"; }
531 if (0) { case AST_BIT_XOR: txt = "^"; }
532 if (0) { case AST_BIT_XNOR: txt = "~^"; }
533 if (0) { case AST_SHIFT_LEFT: txt = "<<"; }
534 if (0) { case AST_SHIFT_RIGHT: txt = ">>"; }
535 if (0) { case AST_SHIFT_SLEFT: txt = "<<<"; }
536 if (0) { case AST_SHIFT_SRIGHT: txt = ">>>"; }
537 if (0) { case AST_LT: txt = "<"; }
538 if (0) { case AST_LE: txt = "<="; }
539 if (0) { case AST_EQ: txt = "=="; }
540 if (0) { case AST_NE: txt = "!="; }
541 if (0) { case AST_GE: txt = ">="; }
542 if (0) { case AST_GT: txt = ">"; }
543 if (0) { case AST_ADD: txt = "+"; }
544 if (0) { case AST_SUB: txt = "-"; }
545 if (0) { case AST_MUL: txt = "*"; }
546 if (0) { case AST_DIV: txt = "/"; }
547 if (0) { case AST_MOD: txt = "%"; }
548 if (0) { case AST_POW: txt = "**"; }
549 if (0) { case AST_LOGIC_AND: txt = "&&"; }
550 if (0) { case AST_LOGIC_OR: txt = "||"; }
551 fprintf(f, "(");
552 children[0]->dumpVlog(f, "");
553 fprintf(f, ")%s(", txt.c_str());
554 children[1]->dumpVlog(f, "");
555 fprintf(f, ")");
556 break;
557
558 case AST_TERNARY:
559 fprintf(f, "(");
560 children[0]->dumpVlog(f, "");
561 fprintf(f, ") ? (");
562 children[1]->dumpVlog(f, "");
563 fprintf(f, ") : (");
564 children[2]->dumpVlog(f, "");
565 fprintf(f, ")");
566 break;
567
568 default:
569 std::string type_name = type2str(type);
570 fprintf(f, "%s" "/** %s **/%s", indent.c_str(), type_name.c_str(), indent.empty() ? "" : "\n");
571 // dumpAst(f, indent, NULL);
572 }
573 }
574
575 // check if two AST nodes are identical
576 bool AstNode::operator==(const AstNode &other) const
577 {
578 if (type != other.type)
579 return false;
580 if (children.size() != other.children.size())
581 return false;
582 if (str != other.str)
583 return false;
584 if (bits != other.bits)
585 return false;
586 if (is_input != other.is_input)
587 return false;
588 if (is_output != other.is_output)
589 return false;
590 if (is_reg != other.is_reg)
591 return false;
592 if (is_signed != other.is_signed)
593 return false;
594 if (range_valid != other.range_valid)
595 return false;
596 if (port_id != other.port_id)
597 return false;
598 if (range_left != other.range_left)
599 return false;
600 if (range_right != other.range_right)
601 return false;
602 if (integer != other.integer)
603 return false;
604 for (size_t i = 0; i < children.size(); i++)
605 if (*children[i] != *other.children[i])
606 return false;
607 return true;
608 }
609
610 // check if two AST nodes are not identical
611 bool AstNode::operator!=(const AstNode &other) const
612 {
613 return !(*this == other);
614 }
615
616 // check if this AST contains the given node
617 bool AstNode::contains(const AstNode *other) const
618 {
619 if (this == other)
620 return true;
621 for (auto child : children)
622 if (child->contains(other))
623 return true;
624 return false;
625 }
626
627 // create an AST node for a constant (using a 32 bit int as value)
628 AstNode *AstNode::mkconst_int(uint32_t v, bool is_signed, int width)
629 {
630 AstNode *node = new AstNode(AST_CONSTANT);
631 node->integer = v;
632 node->is_signed = is_signed;
633 for (int i = 0; i < width; i++) {
634 node->bits.push_back((v & 1) ? RTLIL::S1 : RTLIL::S0);
635 v = v >> 1;
636 }
637 node->range_valid = true;
638 node->range_left = width-1;
639 node->range_right = 0;
640 return node;
641 }
642
643 // create an AST node for a constant (using a bit vector as value)
644 AstNode *AstNode::mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed)
645 {
646 AstNode *node = new AstNode(AST_CONSTANT);
647 node->is_signed = is_signed;
648 node->bits = v;
649 for (size_t i = 0; i < 32; i++) {
650 if (i < node->bits.size())
651 node->integer |= (node->bits[i] == RTLIL::S1) << i;
652 else if (is_signed)
653 node->integer |= (node->bits.back() == RTLIL::S1) << i;
654 }
655 node->range_valid = true;
656 node->range_left = node->bits.size()-1;
657 node->range_right = 0;
658 return node;
659 }
660
661 RTLIL::Const AstNode::bitsAsConst(int width, bool is_signed)
662 {
663 std::vector<RTLIL::State> bits = this->bits;
664 if (width >= 0 && width < int(bits.size()))
665 bits.resize(width);
666 if (width >= 0 && width > int(bits.size())) {
667 RTLIL::State extbit = RTLIL::State::S0;
668 if (is_signed && !bits.empty())
669 extbit = bits.back();
670 while (width > int(bits.size()))
671 bits.push_back(extbit);
672 }
673 return RTLIL::Const(bits);
674 }
675
676 RTLIL::Const AstNode::bitsAsConst(int width)
677 {
678 return bitsAsConst(width, is_signed);
679 }
680
681 RTLIL::Const AstNode::asAttrConst()
682 {
683 log_assert(type == AST_CONSTANT);
684
685 RTLIL::Const val;
686 val.bits = bits;
687
688 if (!str.empty()) {
689 val.flags |= RTLIL::CONST_FLAG_STRING;
690 log_assert(val.decode_string() == str);
691 }
692
693 return val;
694 }
695
696 RTLIL::Const AstNode::asParaConst()
697 {
698 RTLIL::Const val = asAttrConst();
699 if (is_signed)
700 val.flags |= RTLIL::CONST_FLAG_SIGNED;
701 return val;
702 }
703
704 bool AstNode::asBool()
705 {
706 log_assert(type == AST_CONSTANT);
707 for (auto &bit : bits)
708 if (bit == RTLIL::State::S1)
709 return true;
710 return false;
711 }
712
713 // create a new AstModule from an AST_MODULE AST node
714 static AstModule* process_module(AstNode *ast)
715 {
716 assert(ast->type == AST_MODULE);
717 log("Generating RTLIL representation for module `%s'.\n", ast->str.c_str());
718
719 current_module = new AstModule;
720 current_module->ast = NULL;
721 current_module->name = ast->str;
722 current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum);
723
724 current_ast_mod = ast;
725 AstNode *ast_before_simplify = ast->clone();
726
727 if (flag_dump_ast1) {
728 log("Dumping verilog AST before simplification:\n");
729 ast->dumpAst(NULL, " ");
730 log("--- END OF AST DUMP ---\n");
731 }
732
733 while (ast->simplify(!flag_noopt, false, false, 0, -1, false)) { }
734
735 if (flag_dump_ast2) {
736 log("Dumping verilog AST after simplification:\n");
737 ast->dumpAst(NULL, " ");
738 log("--- END OF AST DUMP ---\n");
739 }
740
741 if (flag_dump_vlog) {
742 log("Dumping verilog AST (as requested by dump_vlog option):\n");
743 ast->dumpVlog(NULL, " ");
744 log("--- END OF AST DUMP ---\n");
745 }
746
747 if (flag_lib) {
748 std::vector<AstNode*> new_children;
749 for (auto child : ast->children) {
750 if (child->type == AST_WIRE && (child->is_input || child->is_output))
751 new_children.push_back(child);
752 else
753 delete child;
754 }
755 ast->children.swap(new_children);
756 ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false);
757 }
758
759 ignoreThisSignalsInInitial = RTLIL::SigSpec();
760
761 for (auto &attr : ast->attributes) {
762 if (attr.second->type != AST_CONSTANT)
763 log_error("Attribute `%s' with non-constant value at %s:%d!\n",
764 attr.first.c_str(), ast->filename.c_str(), ast->linenum);
765 current_module->attributes[attr.first] = attr.second->asAttrConst();
766 }
767 for (size_t i = 0; i < ast->children.size(); i++) {
768 AstNode *node = ast->children[i];
769 if (node->type == AST_WIRE || node->type == AST_MEMORY)
770 node->genRTLIL();
771 }
772 for (size_t i = 0; i < ast->children.size(); i++) {
773 AstNode *node = ast->children[i];
774 if (node->type != AST_WIRE && node->type != AST_MEMORY && node->type != AST_INITIAL)
775 node->genRTLIL();
776 }
777
778 ignoreThisSignalsInInitial.sort_and_unify();
779
780 for (size_t i = 0; i < ast->children.size(); i++) {
781 AstNode *node = ast->children[i];
782 if (node->type == AST_INITIAL)
783 node->genRTLIL();
784 }
785
786 ignoreThisSignalsInInitial = RTLIL::SigSpec();
787
788 current_module->ast = ast_before_simplify;
789 current_module->nolatches = flag_nolatches;
790 current_module->nomem2reg = flag_nomem2reg;
791 current_module->mem2reg = flag_mem2reg;
792 current_module->lib = flag_lib;
793 current_module->noopt = flag_noopt;
794 return current_module;
795 }
796
797 // create AstModule instances for all modules in the AST tree and add them to 'design'
798 void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool ignore_redef)
799 {
800 current_ast = ast;
801 flag_dump_ast1 = dump_ast1;
802 flag_dump_ast2 = dump_ast2;
803 flag_dump_vlog = dump_vlog;
804 flag_nolatches = nolatches;
805 flag_nomem2reg = nomem2reg;
806 flag_mem2reg = mem2reg;
807 flag_lib = lib;
808 flag_noopt = noopt;
809
810 assert(current_ast->type == AST_DESIGN);
811 for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) {
812 if (design->modules.count((*it)->str) != 0) {
813 if (!ignore_redef)
814 log_error("Re-definition of module `%s' at %s:%d!\n",
815 (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
816 log_error("Ignoring re-definition of module `%s' at %s:%d!\n",
817 (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
818 continue;
819 }
820 design->modules[(*it)->str] = process_module(*it);
821 }
822 }
823
824 // AstModule destructor
825 AstModule::~AstModule()
826 {
827 if (ast != NULL)
828 delete ast;
829 }
830
831 // create a new parametric module (when needed) and return the name of the generated module
832 RTLIL::IdString AstModule::derive(RTLIL::Design *design, std::map<RTLIL::IdString, RTLIL::Const> parameters)
833 {
834 log_header("Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", name.c_str());
835
836 current_ast = NULL;
837 flag_dump_ast1 = false;
838 flag_dump_ast2 = false;
839 flag_dump_vlog = false;
840 flag_nolatches = nolatches;
841 flag_nomem2reg = nomem2reg;
842 flag_mem2reg = mem2reg;
843 flag_lib = lib;
844 flag_noopt = noopt;
845 use_internal_line_num();
846
847 std::string para_info;
848 std::vector<unsigned char> hash_data;
849 hash_data.insert(hash_data.end(), name.begin(), name.end());
850 hash_data.push_back(0);
851
852 AstNode *new_ast = ast->clone();
853
854 int para_counter = 0;
855 for (auto it = new_ast->children.begin(); it != new_ast->children.end(); it++) {
856 AstNode *child = *it;
857 if (child->type != AST_PARAMETER)
858 continue;
859 para_counter++;
860 std::string para_id = child->str;
861 if (parameters.count(para_id) > 0) {
862 log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
863 rewrite_parameter:
864 para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
865 delete child->children.at(0);
866 child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0);
867 hash_data.insert(hash_data.end(), child->str.begin(), child->str.end());
868 hash_data.push_back(0);
869 hash_data.insert(hash_data.end(), parameters[para_id].bits.begin(), parameters[para_id].bits.end());
870 hash_data.push_back(0xff);
871 parameters.erase(para_id);
872 continue;
873 }
874 para_id = stringf("$%d", para_counter);
875 if (parameters.count(para_id) > 0) {
876 log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
877 goto rewrite_parameter;
878 }
879 }
880 if (parameters.size() > 0)
881 log_error("Requested parameter `%s' does not exist in module `%s'!\n", parameters.begin()->first.c_str(), name.c_str());
882
883 std::string modname;
884
885 if (para_info.size() > 60)
886 {
887 unsigned char hash[20];
888 unsigned char *hash_data2 = new unsigned char[hash_data.size()];
889 for (size_t i = 0; i < hash_data.size(); i++)
890 hash_data2[i] = hash_data[i];
891 sha1::calc(hash_data2, hash_data.size(), hash);
892 delete[] hash_data2;
893
894 char hexstring[41];
895 sha1::toHexString(hash, hexstring);
896
897 modname = "$paramod$" + std::string(hexstring) + name;
898 }
899 else
900 {
901 modname = "$paramod" + name + para_info;
902 }
903
904 if (design->modules.count(modname) == 0) {
905 new_ast->str = modname;
906 design->modules[modname] = process_module(new_ast);
907 design->modules[modname]->check();
908 } else {
909 log("Found cached RTLIL representation for module `%s'.\n", modname.c_str());
910 }
911
912 delete new_ast;
913 return modname;
914 }
915
916 RTLIL::Module *AstModule::clone() const
917 {
918 AstModule *new_mod = new AstModule;
919 cloneInto(new_mod);
920
921 new_mod->ast = ast->clone();
922 new_mod->nolatches = nolatches;
923 new_mod->nomem2reg = nomem2reg;
924 new_mod->mem2reg = mem2reg;
925 new_mod->lib = lib;
926 new_mod->noopt = noopt;
927
928 return new_mod;
929 }
930
931 // internal dummy line number callbacks
932 namespace {
933 int internal_line_num;
934 void internal_set_line_num(int n) {
935 internal_line_num = n;
936 }
937 int internal_get_line_num() {
938 return internal_line_num;
939 }
940 }
941
942 // use internal dummy line number callbacks
943 void AST::use_internal_line_num()
944 {
945 set_line_num = &internal_set_line_num;
946 get_line_num = &internal_get_line_num;
947 }
948