4baed3bfc482eae31857217e9160f807028d3500
[yosys.git] / frontends / ast / simplify.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 "frontends/verilog/verilog_frontend.h"
32 #include "ast.h"
33
34 #include <sstream>
35 #include <stdarg.h>
36 #include <stdlib.h>
37 #include <math.h>
38
39 YOSYS_NAMESPACE_BEGIN
40
41 using namespace AST;
42 using namespace AST_INTERNAL;
43
44 // convert the AST into a simpler AST that has all parameters substituted by their
45 // values, unrolled for-loops, expanded generate blocks, etc. when this function
46 // is done with an AST it can be converted into RTLIL using genRTLIL().
47 //
48 // this function also does all name resolving and sets the id2ast member of all
49 // nodes that link to a different node using names and lexical scoping.
50 bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param)
51 {
52 static int recursion_counter = 0;
53 static pair<string, int> last_blocking_assignment_warn;
54 static bool deep_recursion_warning = false;
55
56 if (recursion_counter++ == 1000 && deep_recursion_warning) {
57 log_warning("Deep recursion in AST simplifier.\nDoes this design contain insanely long expressions?\n");
58 deep_recursion_warning = false;
59 }
60
61 AstNode *newNode = NULL;
62 bool did_something = false;
63
64 #if 0
65 log("-------------\n");
66 log("AST simplify[%d] depth %d at %s:%d on %s %p:\n", stage, recursion_counter, filename.c_str(), linenum, type2str(type).c_str(), this);
67 log("const_fold=%d, at_zero=%d, in_lvalue=%d, stage=%d, width_hint=%d, sign_hint=%d, in_param=%d\n",
68 int(const_fold), int(at_zero), int(in_lvalue), int(stage), int(width_hint), int(sign_hint), int(in_param));
69 // dumpAst(NULL, "> ");
70 #endif
71
72 if (stage == 0)
73 {
74 log_assert(type == AST_MODULE);
75 last_blocking_assignment_warn = pair<string, int>();
76
77 deep_recursion_warning = true;
78 while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint, in_param)) { }
79
80 if (!flag_nomem2reg && !get_bool_attribute("\\nomem2reg"))
81 {
82 dict<AstNode*, pool<std::string>> mem2reg_places;
83 dict<AstNode*, uint32_t> mem2reg_candidates, dummy_proc_flags;
84 uint32_t flags = flag_mem2reg ? AstNode::MEM2REG_FL_ALL : 0;
85 mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, dummy_proc_flags, flags);
86
87 pool<AstNode*> mem2reg_set;
88 for (auto &it : mem2reg_candidates)
89 {
90 AstNode *mem = it.first;
91 uint32_t memflags = it.second;
92 bool this_nomeminit = flag_nomeminit;
93 log_assert((memflags & ~0x00ffff00) == 0);
94
95 if (mem->get_bool_attribute("\\nomem2reg"))
96 continue;
97
98 if (mem->get_bool_attribute("\\nomeminit") || get_bool_attribute("\\nomeminit"))
99 this_nomeminit = true;
100
101 if (memflags & AstNode::MEM2REG_FL_FORCED)
102 goto silent_activate;
103
104 if (memflags & AstNode::MEM2REG_FL_EQ2)
105 goto verbose_activate;
106
107 if (memflags & AstNode::MEM2REG_FL_SET_ASYNC)
108 goto verbose_activate;
109
110 if ((memflags & AstNode::MEM2REG_FL_SET_INIT) && (memflags & AstNode::MEM2REG_FL_SET_ELSE) && this_nomeminit)
111 goto verbose_activate;
112
113 if (memflags & AstNode::MEM2REG_FL_CMPLX_LHS)
114 goto verbose_activate;
115
116 // log("Note: Not replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
117 continue;
118
119 verbose_activate:
120 if (mem2reg_set.count(mem) == 0) {
121 std::string message = stringf("Replacing memory %s with list of registers.", mem->str.c_str());
122 bool first_element = true;
123 for (auto &place : mem2reg_places[it.first]) {
124 message += stringf("%s%s", first_element ? " See " : ", ", place.c_str());
125 first_element = false;
126 }
127 log_warning("%s\n", message.c_str());
128 }
129
130 silent_activate:
131 // log("Note: Replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
132 mem2reg_set.insert(mem);
133 }
134
135 for (auto node : mem2reg_set)
136 {
137 int mem_width, mem_size, addr_bits;
138 node->meminfo(mem_width, mem_size, addr_bits);
139
140 for (int i = 0; i < mem_size; i++) {
141 AstNode *reg = new AstNode(AST_WIRE, new AstNode(AST_RANGE,
142 mkconst_int(mem_width-1, true), mkconst_int(0, true)));
143 reg->str = stringf("%s[%d]", node->str.c_str(), i);
144 reg->is_reg = true;
145 reg->is_signed = node->is_signed;
146 children.push_back(reg);
147 while (reg->simplify(true, false, false, 1, -1, false, false)) { }
148 }
149 }
150
151 AstNode *async_block = NULL;
152 while (mem2reg_as_needed_pass2(mem2reg_set, this, NULL, async_block)) { }
153
154 vector<AstNode*> delnodes;
155 mem2reg_remove(mem2reg_set, delnodes);
156
157 for (auto node : delnodes)
158 delete node;
159 }
160
161 while (simplify(const_fold, at_zero, in_lvalue, 2, width_hint, sign_hint, in_param)) { }
162 recursion_counter--;
163 return false;
164 }
165
166 current_filename = filename;
167 set_line_num(linenum);
168
169 // we do not look inside a task or function
170 // (but as soon as a task or function is instantiated we process the generated AST as usual)
171 if (type == AST_FUNCTION || type == AST_TASK) {
172 recursion_counter--;
173 return false;
174 }
175
176 // deactivate all calls to non-synthesis system tasks
177 // note that $display, $finish, and $stop are used for synthesis-time DRC so they're not in this list
178 if ((type == AST_FCALL || type == AST_TCALL) && (str == "$strobe" || str == "$monitor" || str == "$time" ||
179 str == "$dumpfile" || str == "$dumpvars" || str == "$dumpon" || str == "$dumpoff" || str == "$dumpall")) {
180 log_warning("Ignoring call to system %s %s at %s:%d.\n", type == AST_FCALL ? "function" : "task", str.c_str(), filename.c_str(), linenum);
181 delete_children();
182 str = std::string();
183 }
184
185 if ((type == AST_TCALL) && (str == "$display" || str == "$write") && (!current_always || current_always->type != AST_INITIAL)) {
186 log_warning("System task `%s' outside initial block is unsupported at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
187 delete_children();
188 str = std::string();
189 }
190
191 // print messages if this a call to $display() or $write()
192 // This code implements only a small subset of Verilog-2005 $display() format specifiers,
193 // but should be good enough for most uses
194 if ((type == AST_TCALL) && ((str == "$display") || (str == "$write")))
195 {
196 int nargs = GetSize(children);
197 if (nargs < 1)
198 log_error("System task `%s' got %d arguments, expected >= 1 at %s:%d.\n",
199 str.c_str(), int(children.size()), filename.c_str(), linenum);
200
201 // First argument is the format string
202 AstNode *node_string = children[0];
203 while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
204 if (node_string->type != AST_CONSTANT)
205 log_error("Failed to evaluate system task `%s' with non-constant 1st argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
206 std::string sformat = node_string->bitsAsConst().decode_string();
207
208 // Other arguments are placeholders. Process the string as we go through it
209 std::string sout;
210 int next_arg = 1;
211 for (size_t i = 0; i < sformat.length(); i++)
212 {
213 // format specifier
214 if (sformat[i] == '%')
215 {
216 // If there's no next character, that's a problem
217 if (i+1 >= sformat.length())
218 log_error("System task `%s' called with `%%' at end of string at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
219
220 char cformat = sformat[++i];
221
222 // %% is special, does not need a matching argument
223 if (cformat == '%')
224 {
225 sout += '%';
226 continue;
227 }
228
229 // Simplify the argument
230 AstNode *node_arg = nullptr;
231
232 // Everything from here on depends on the format specifier
233 switch (cformat)
234 {
235 case 's':
236 case 'S':
237 case 'd':
238 case 'D':
239 case 'x':
240 case 'X':
241 if (next_arg >= GetSize(children))
242 log_error("Missing argument for %%%c format specifier in system task `%s' at %s:%d.\n",
243 cformat, str.c_str(), filename.c_str(), linenum);
244
245 node_arg = children[next_arg++];
246 while (node_arg->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
247 if (node_arg->type != AST_CONSTANT)
248 log_error("Failed to evaluate system task `%s' with non-constant argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
249 break;
250
251 case 'm':
252 case 'M':
253 break;
254
255 default:
256 log_error("System task `%s' called with invalid/unsupported format specifier at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
257 break;
258 }
259
260 switch (cformat)
261 {
262 case 's':
263 case 'S':
264 sout += node_arg->bitsAsConst().decode_string();
265 break;
266
267 case 'd':
268 case 'D':
269 {
270 char tmp[128];
271 snprintf(tmp, sizeof(tmp), "%d", node_arg->bitsAsConst().as_int());
272 sout += tmp;
273 }
274 break;
275
276 case 'x':
277 case 'X':
278 {
279 char tmp[128];
280 snprintf(tmp, sizeof(tmp), "%x", node_arg->bitsAsConst().as_int());
281 sout += tmp;
282 }
283 break;
284
285 case 'm':
286 case 'M':
287 sout += log_id(current_module->name);
288 break;
289
290 default:
291 log_abort();
292 }
293 }
294
295 // not a format specifier
296 else
297 sout += sformat[i];
298 }
299
300 // Finally, print the message (only include a \n for $display, not for $write)
301 log("%s", sout.c_str());
302 if (str == "$display")
303 log("\n");
304 delete_children();
305 str = std::string();
306 }
307
308 // activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
309 if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX)
310 const_fold = true;
311 if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM))
312 const_fold = true;
313
314 // in certain cases a function must be evaluated constant. this is what in_param controls.
315 if (type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_PREFIX)
316 in_param = true;
317
318 std::map<std::string, AstNode*> backup_scope;
319
320 // create name resolution entries for all objects with names
321 // also merge multiple declarations for the same wire (e.g. "output foobar; reg foobar;")
322 if (type == AST_MODULE) {
323 current_scope.clear();
324 std::map<std::string, AstNode*> this_wire_scope;
325 for (size_t i = 0; i < children.size(); i++) {
326 AstNode *node = children[i];
327 if (node->type == AST_WIRE) {
328 if (this_wire_scope.count(node->str) > 0) {
329 AstNode *first_node = this_wire_scope[node->str];
330 if (!node->is_input && !node->is_output && node->is_reg && node->children.size() == 0)
331 goto wires_are_compatible;
332 if (first_node->children.size() == 0 && node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
333 AstNode *r = node->children[0];
334 if (r->range_valid && r->range_left == 0 && r->range_right == 0) {
335 delete r;
336 node->children.pop_back();
337 }
338 }
339 if (first_node->children.size() != node->children.size())
340 goto wires_are_incompatible;
341 for (size_t j = 0; j < node->children.size(); j++) {
342 AstNode *n1 = first_node->children[j], *n2 = node->children[j];
343 if (n1->type == AST_RANGE && n2->type == AST_RANGE && n1->range_valid && n2->range_valid) {
344 if (n1->range_left != n2->range_left)
345 goto wires_are_incompatible;
346 if (n1->range_right != n2->range_right)
347 goto wires_are_incompatible;
348 } else if (*n1 != *n2)
349 goto wires_are_incompatible;
350 }
351 if (first_node->range_left != node->range_left)
352 goto wires_are_incompatible;
353 if (first_node->range_right != node->range_right)
354 goto wires_are_incompatible;
355 if (first_node->port_id == 0 && (node->is_input || node->is_output))
356 goto wires_are_incompatible;
357 wires_are_compatible:
358 if (node->is_input)
359 first_node->is_input = true;
360 if (node->is_output)
361 first_node->is_output = true;
362 if (node->is_reg)
363 first_node->is_reg = true;
364 if (node->is_signed)
365 first_node->is_signed = true;
366 for (auto &it : node->attributes) {
367 if (first_node->attributes.count(it.first) > 0)
368 delete first_node->attributes[it.first];
369 first_node->attributes[it.first] = it.second->clone();
370 }
371 children.erase(children.begin()+(i--));
372 did_something = true;
373 delete node;
374 continue;
375 wires_are_incompatible:
376 if (stage > 1)
377 log_error("Incompatible re-declaration of wire %s at %s:%d.\n", node->str.c_str(), filename.c_str(), linenum);
378 continue;
379 }
380 this_wire_scope[node->str] = node;
381 }
382 if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
383 node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL) {
384 backup_scope[node->str] = current_scope[node->str];
385 current_scope[node->str] = node;
386 }
387 }
388 for (size_t i = 0; i < children.size(); i++) {
389 AstNode *node = children[i];
390 if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY)
391 while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM))
392 did_something = true;
393 }
394 }
395
396 auto backup_current_block = current_block;
397 auto backup_current_block_child = current_block_child;
398 auto backup_current_top_block = current_top_block;
399 auto backup_current_always = current_always;
400 auto backup_current_always_clocked = current_always_clocked;
401
402 if (type == AST_ALWAYS || type == AST_INITIAL)
403 {
404 current_always = this;
405 current_always_clocked = false;
406
407 if (type == AST_ALWAYS)
408 for (auto child : children) {
409 if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE)
410 current_always_clocked = true;
411 if (child->type == AST_EDGE && GetSize(child->children) == 1 &&
412 child->children[0]->type == AST_IDENTIFIER && child->children[0]->str == "\\$global_clock")
413 current_always_clocked = true;
414 }
415 }
416
417 int backup_width_hint = width_hint;
418 bool backup_sign_hint = sign_hint;
419
420 bool detect_width_simple = false;
421 bool child_0_is_self_determined = false;
422 bool child_1_is_self_determined = false;
423 bool child_2_is_self_determined = false;
424 bool children_are_self_determined = false;
425 bool reset_width_after_children = false;
426
427 switch (type)
428 {
429 case AST_ASSIGN_EQ:
430 case AST_ASSIGN_LE:
431 case AST_ASSIGN:
432 while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, in_param) == true)
433 did_something = true;
434 while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, in_param) == true)
435 did_something = true;
436 children[0]->detectSignWidth(backup_width_hint, backup_sign_hint);
437 children[1]->detectSignWidth(width_hint, sign_hint);
438 width_hint = max(width_hint, backup_width_hint);
439 child_0_is_self_determined = true;
440 break;
441
442 case AST_PARAMETER:
443 case AST_LOCALPARAM:
444 while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true)
445 did_something = true;
446 children[0]->detectSignWidth(width_hint, sign_hint);
447 if (children.size() > 1 && children[1]->type == AST_RANGE) {
448 while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true)
449 did_something = true;
450 if (!children[1]->range_valid)
451 log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum);
452 width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1);
453 }
454 break;
455
456 case AST_TO_BITS:
457 case AST_TO_SIGNED:
458 case AST_TO_UNSIGNED:
459 case AST_CONCAT:
460 case AST_REPLICATE:
461 case AST_REDUCE_AND:
462 case AST_REDUCE_OR:
463 case AST_REDUCE_XOR:
464 case AST_REDUCE_XNOR:
465 case AST_REDUCE_BOOL:
466 detect_width_simple = true;
467 children_are_self_determined = true;
468 break;
469
470 case AST_NEG:
471 case AST_BIT_NOT:
472 case AST_POS:
473 case AST_BIT_AND:
474 case AST_BIT_OR:
475 case AST_BIT_XOR:
476 case AST_BIT_XNOR:
477 case AST_ADD:
478 case AST_SUB:
479 case AST_MUL:
480 case AST_DIV:
481 case AST_MOD:
482 detect_width_simple = true;
483 break;
484
485 case AST_SHIFT_LEFT:
486 case AST_SHIFT_RIGHT:
487 case AST_SHIFT_SLEFT:
488 case AST_SHIFT_SRIGHT:
489 case AST_POW:
490 detect_width_simple = true;
491 child_1_is_self_determined = true;
492 break;
493
494 case AST_LT:
495 case AST_LE:
496 case AST_EQ:
497 case AST_NE:
498 case AST_EQX:
499 case AST_NEX:
500 case AST_GE:
501 case AST_GT:
502 width_hint = -1;
503 sign_hint = true;
504 for (auto child : children) {
505 while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true)
506 did_something = true;
507 child->detectSignWidthWorker(width_hint, sign_hint);
508 }
509 reset_width_after_children = true;
510 break;
511
512 case AST_LOGIC_AND:
513 case AST_LOGIC_OR:
514 case AST_LOGIC_NOT:
515 detect_width_simple = true;
516 children_are_self_determined = true;
517 break;
518
519 case AST_TERNARY:
520 detect_width_simple = true;
521 child_0_is_self_determined = true;
522 break;
523
524 case AST_MEMRD:
525 detect_width_simple = true;
526 children_are_self_determined = true;
527 break;
528
529 case AST_FCALL:
530 case AST_TCALL:
531 children_are_self_determined = true;
532 break;
533
534 default:
535 width_hint = -1;
536 sign_hint = false;
537 }
538
539 if (detect_width_simple && width_hint < 0) {
540 if (type == AST_REPLICATE)
541 while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, true) == true)
542 did_something = true;
543 for (auto child : children)
544 while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true)
545 did_something = true;
546 detectSignWidth(width_hint, sign_hint);
547 }
548
549 if (type == AST_FCALL && str == "\\$past")
550 detectSignWidth(width_hint, sign_hint);
551
552 if (type == AST_TERNARY) {
553 int width_hint_left, width_hint_right;
554 bool sign_hint_left, sign_hint_right;
555 bool found_real_left, found_real_right;
556 children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left);
557 children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right);
558 if (found_real_left || found_real_right) {
559 child_1_is_self_determined = true;
560 child_2_is_self_determined = true;
561 }
562 }
563
564 if (type == AST_CONDX && children.size() > 0 && children.at(0)->type == AST_CONSTANT) {
565 for (auto &bit : children.at(0)->bits)
566 if (bit == State::Sz || bit == State::Sx)
567 bit = State::Sa;
568 }
569
570 if (type == AST_CONDZ && children.size() > 0 && children.at(0)->type == AST_CONSTANT) {
571 for (auto &bit : children.at(0)->bits)
572 if (bit == State::Sz)
573 bit = State::Sa;
574 }
575
576 if (const_fold && type == AST_CASE)
577 {
578 while (children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { }
579 if (children[0]->type == AST_CONSTANT && children[0]->bits_only_01()) {
580 std::vector<AstNode*> new_children;
581 new_children.push_back(children[0]);
582 for (int i = 1; i < GetSize(children); i++) {
583 AstNode *child = children[i];
584 log_assert(child->type == AST_COND || child->type == AST_CONDX || child->type == AST_CONDZ);
585 for (auto v : child->children) {
586 if (v->type == AST_DEFAULT)
587 goto keep_const_cond;
588 if (v->type == AST_BLOCK)
589 continue;
590 while (v->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { }
591 if (v->type == AST_CONSTANT && v->bits_only_01()) {
592 if (v->bits == children[0]->bits) {
593 while (i+1 < GetSize(children))
594 delete children[++i];
595 goto keep_const_cond;
596 }
597 continue;
598 }
599 goto keep_const_cond;
600 }
601 if (0)
602 keep_const_cond:
603 new_children.push_back(child);
604 else
605 delete child;
606 }
607 new_children.swap(children);
608 }
609 }
610
611 // simplify all children first
612 // (iterate by index as e.g. auto wires can add new children in the process)
613 for (size_t i = 0; i < children.size(); i++) {
614 bool did_something_here = true;
615 if ((type == AST_GENFOR || type == AST_FOR) && i >= 3)
616 break;
617 if ((type == AST_GENIF || type == AST_GENCASE) && i >= 1)
618 break;
619 if (type == AST_GENBLOCK)
620 break;
621 if (type == AST_BLOCK && !str.empty())
622 break;
623 if (type == AST_PREFIX && i >= 1)
624 break;
625 while (did_something_here && i < children.size()) {
626 bool const_fold_here = const_fold, in_lvalue_here = in_lvalue;
627 int width_hint_here = width_hint;
628 bool sign_hint_here = sign_hint;
629 bool in_param_here = in_param;
630 if (i == 0 && (type == AST_REPLICATE || type == AST_WIRE))
631 const_fold_here = true, in_param_here = true;
632 if (type == AST_PARAMETER || type == AST_LOCALPARAM)
633 const_fold_here = true;
634 if (i == 0 && (type == AST_ASSIGN || type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE))
635 in_lvalue_here = true;
636 if (type == AST_BLOCK) {
637 current_block = this;
638 current_block_child = children[i];
639 }
640 if ((type == AST_ALWAYS || type == AST_INITIAL) && children[i]->type == AST_BLOCK)
641 current_top_block = children[i];
642 if (i == 0 && child_0_is_self_determined)
643 width_hint_here = -1, sign_hint_here = false;
644 if (i == 1 && child_1_is_self_determined)
645 width_hint_here = -1, sign_hint_here = false;
646 if (i == 2 && child_2_is_self_determined)
647 width_hint_here = -1, sign_hint_here = false;
648 if (children_are_self_determined)
649 width_hint_here = -1, sign_hint_here = false;
650 did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param_here);
651 if (did_something_here)
652 did_something = true;
653 }
654 if (stage == 2 && children[i]->type == AST_INITIAL && current_ast_mod != this) {
655 current_ast_mod->children.push_back(children[i]);
656 children.erase(children.begin() + (i--));
657 did_something = true;
658 }
659 }
660 for (auto &attr : attributes) {
661 while (attr.second->simplify(true, false, false, stage, -1, false, true))
662 did_something = true;
663 }
664
665 if (reset_width_after_children) {
666 width_hint = backup_width_hint;
667 sign_hint = backup_sign_hint;
668 if (width_hint < 0)
669 detectSignWidth(width_hint, sign_hint);
670 }
671
672 current_block = backup_current_block;
673 current_block_child = backup_current_block_child;
674 current_top_block = backup_current_top_block;
675 current_always = backup_current_always;
676 current_always_clocked = backup_current_always_clocked;
677
678 for (auto it = backup_scope.begin(); it != backup_scope.end(); it++) {
679 if (it->second == NULL)
680 current_scope.erase(it->first);
681 else
682 current_scope[it->first] = it->second;
683 }
684
685 current_filename = filename;
686 set_line_num(linenum);
687
688 if (type == AST_MODULE)
689 current_scope.clear();
690
691 // convert defparam nodes to cell parameters
692 if (type == AST_DEFPARAM && !children.empty())
693 {
694 if (children[0]->type != AST_IDENTIFIER)
695 log_error("Module name in defparam at %s:%d contains non-constant expressions!\n", filename.c_str(), linenum);
696
697 string modname, paramname = children[0]->str;
698
699 size_t pos = paramname.rfind('.');
700
701 while (pos != 0 && pos != std::string::npos)
702 {
703 modname = paramname.substr(0, pos);
704
705 if (current_scope.count(modname))
706 break;
707
708 pos = paramname.rfind('.', pos - 1);
709 }
710
711 if (pos == std::string::npos)
712 log_error("Can't find object for defparam `%s` at %s:%d!\n", RTLIL::unescape_id(paramname).c_str(), filename.c_str(), linenum);
713
714 paramname = "\\" + paramname.substr(pos+1);
715
716 if (current_scope.at(modname)->type != AST_CELL)
717 log_error("Defparam argument `%s . %s` does not match a cell at %s:%d!\n",
718 RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paramname).c_str(), filename.c_str(), linenum);
719
720 AstNode *paraset = new AstNode(AST_PARASET, children[1]->clone(), GetSize(children) > 2 ? children[2]->clone() : NULL);
721 paraset->str = paramname;
722
723 AstNode *cell = current_scope.at(modname);
724 cell->children.insert(cell->children.begin() + 1, paraset);
725 delete_children();
726 }
727
728 // resolve constant prefixes
729 if (type == AST_PREFIX) {
730 if (children[0]->type != AST_CONSTANT) {
731 // dumpAst(NULL, "> ");
732 log_error("Index in generate block prefix syntax at %s:%d is not constant!\n", filename.c_str(), linenum);
733 }
734 if (children[1]->type == AST_PREFIX)
735 children[1]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param);
736 log_assert(children[1]->type == AST_IDENTIFIER);
737 newNode = children[1]->clone();
738 const char *second_part = children[1]->str.c_str();
739 if (second_part[0] == '\\')
740 second_part++;
741 newNode->str = stringf("%s[%d].%s", str.c_str(), children[0]->integer, second_part);
742 goto apply_newNode;
743 }
744
745 // evaluate TO_BITS nodes
746 if (type == AST_TO_BITS) {
747 if (children[0]->type != AST_CONSTANT)
748 log_error("Left operand of to_bits expression is not constant at %s:%d!\n", filename.c_str(), linenum);
749 if (children[1]->type != AST_CONSTANT)
750 log_error("Right operand of to_bits expression is not constant at %s:%d!\n", filename.c_str(), linenum);
751 RTLIL::Const new_value = children[1]->bitsAsConst(children[0]->bitsAsConst().as_int(), children[1]->is_signed);
752 newNode = mkconst_bits(new_value.bits, children[1]->is_signed);
753 goto apply_newNode;
754 }
755
756 // annotate constant ranges
757 if (type == AST_RANGE) {
758 bool old_range_valid = range_valid;
759 range_valid = false;
760 range_swapped = false;
761 range_left = -1;
762 range_right = 0;
763 log_assert(children.size() >= 1);
764 if (children[0]->type == AST_CONSTANT) {
765 range_valid = true;
766 range_left = children[0]->integer;
767 if (children.size() == 1)
768 range_right = range_left;
769 }
770 if (children.size() >= 2) {
771 if (children[1]->type == AST_CONSTANT)
772 range_right = children[1]->integer;
773 else
774 range_valid = false;
775 }
776 if (old_range_valid != range_valid)
777 did_something = true;
778 if (range_valid && range_left >= 0 && range_right > range_left) {
779 int tmp = range_right;
780 range_right = range_left;
781 range_left = tmp;
782 range_swapped = true;
783 }
784 }
785
786 // annotate wires with their ranges
787 if (type == AST_WIRE) {
788 if (children.size() > 0) {
789 if (children[0]->range_valid) {
790 if (!range_valid)
791 did_something = true;
792 range_valid = true;
793 range_swapped = children[0]->range_swapped;
794 range_left = children[0]->range_left;
795 range_right = children[0]->range_right;
796 }
797 } else {
798 if (!range_valid)
799 did_something = true;
800 range_valid = true;
801 range_swapped = false;
802 range_left = 0;
803 range_right = 0;
804 }
805 }
806
807 // resolve multiranges on memory decl
808 if (type == AST_MEMORY && children.size() > 1 && children[1]->type == AST_MULTIRANGE)
809 {
810 int total_size = 1;
811 multirange_dimensions.clear();
812 for (auto range : children[1]->children) {
813 if (!range->range_valid)
814 log_error("Non-constant range on memory decl at %s:%d.\n", filename.c_str(), linenum);
815 multirange_dimensions.push_back(min(range->range_left, range->range_right));
816 multirange_dimensions.push_back(max(range->range_left, range->range_right) - min(range->range_left, range->range_right) + 1);
817 total_size *= multirange_dimensions.back();
818 }
819 delete children[1];
820 children[1] = new AstNode(AST_RANGE, AstNode::mkconst_int(0, true), AstNode::mkconst_int(total_size-1, true));
821 did_something = true;
822 }
823
824 // resolve multiranges on memory access
825 if (type == AST_IDENTIFIER && id2ast && id2ast->type == AST_MEMORY && children.size() > 0 && children[0]->type == AST_MULTIRANGE)
826 {
827 AstNode *index_expr = nullptr;
828
829 for (int i = 0; 2*i < GetSize(id2ast->multirange_dimensions); i++)
830 {
831 if (GetSize(children[0]->children) < i)
832 log_error("Insufficient number of array indices for %s at %s:%d.\n", log_id(str), filename.c_str(), linenum);
833
834 AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone();
835
836 if (id2ast->multirange_dimensions[2*i])
837 new_index_expr = new AstNode(AST_SUB, new_index_expr, AstNode::mkconst_int(id2ast->multirange_dimensions[2*i], true));
838
839 if (i == 0)
840 index_expr = new_index_expr;
841 else
842 index_expr = new AstNode(AST_ADD, new AstNode(AST_MUL, index_expr, AstNode::mkconst_int(id2ast->multirange_dimensions[2*i+1], true)), new_index_expr);
843 }
844
845 for (int i = GetSize(id2ast->multirange_dimensions)/2; i < GetSize(children[0]->children); i++)
846 children.push_back(children[0]->children[i]->clone());
847
848 delete children[0];
849 if (index_expr == nullptr)
850 children.erase(children.begin());
851 else
852 children[0] = new AstNode(AST_RANGE, index_expr);
853
854 did_something = true;
855 }
856
857 // trim/extend parameters
858 if (type == AST_PARAMETER || type == AST_LOCALPARAM) {
859 if (children.size() > 1 && children[1]->type == AST_RANGE) {
860 if (!children[1]->range_valid)
861 log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum);
862 int width = std::abs(children[1]->range_left - children[1]->range_right) + 1;
863 if (children[0]->type == AST_REALVALUE) {
864 RTLIL::Const constvalue = children[0]->realAsConst(width);
865 log_warning("converting real value %e to binary %s at %s:%d.\n",
866 children[0]->realvalue, log_signal(constvalue), filename.c_str(), linenum);
867 delete children[0];
868 children[0] = mkconst_bits(constvalue.bits, sign_hint);
869 did_something = true;
870 }
871 if (children[0]->type == AST_CONSTANT) {
872 if (width != int(children[0]->bits.size())) {
873 RTLIL::SigSpec sig(children[0]->bits);
874 sig.extend_u0(width, children[0]->is_signed);
875 AstNode *old_child_0 = children[0];
876 children[0] = mkconst_bits(sig.as_const().bits, is_signed);
877 delete old_child_0;
878 }
879 children[0]->is_signed = is_signed;
880 }
881 range_valid = true;
882 range_swapped = children[1]->range_swapped;
883 range_left = children[1]->range_left;
884 range_right = children[1]->range_right;
885 } else
886 if (children.size() > 1 && children[1]->type == AST_REALVALUE && children[0]->type == AST_CONSTANT) {
887 double as_realvalue = children[0]->asReal(sign_hint);
888 delete children[0];
889 children[0] = new AstNode(AST_REALVALUE);
890 children[0]->realvalue = as_realvalue;
891 did_something = true;
892 }
893 }
894
895 // annotate identifiers using scope resolution and create auto-wires as needed
896 if (type == AST_IDENTIFIER) {
897 if (current_scope.count(str) == 0) {
898 for (auto node : current_ast_mod->children) {
899 if ((node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
900 node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION) && str == node->str) {
901 current_scope[node->str] = node;
902 break;
903 }
904 }
905 }
906 if (current_scope.count(str) == 0) {
907 // log_warning("Creating auto-wire `%s' in module `%s'.\n", str.c_str(), current_ast_mod->str.c_str());
908 AstNode *auto_wire = new AstNode(AST_AUTOWIRE);
909 auto_wire->str = str;
910 current_ast_mod->children.push_back(auto_wire);
911 current_scope[str] = auto_wire;
912 did_something = true;
913 }
914 if (id2ast != current_scope[str]) {
915 id2ast = current_scope[str];
916 did_something = true;
917 }
918 }
919
920 // split memory access with bit select to individual statements
921 if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE && !in_lvalue)
922 {
923 if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1)
924 log_error("Invalid bit-select on memory access at %s:%d!\n", filename.c_str(), linenum);
925
926 int mem_width, mem_size, addr_bits;
927 id2ast->meminfo(mem_width, mem_size, addr_bits);
928
929 int data_range_left = id2ast->children[0]->range_left;
930 int data_range_right = id2ast->children[0]->range_right;
931
932 std::stringstream sstr;
933 sstr << "$mem2bits$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++);
934 std::string wire_id = sstr.str();
935
936 AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(data_range_left, true), mkconst_int(data_range_right, true)));
937 wire->str = wire_id;
938 if (current_block)
939 wire->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
940 current_ast_mod->children.push_back(wire);
941 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
942
943 AstNode *data = clone();
944 delete data->children[1];
945 data->children.pop_back();
946
947 AstNode *assign = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), data);
948 assign->children[0]->str = wire_id;
949
950 if (current_block)
951 {
952 size_t assign_idx = 0;
953 while (assign_idx < current_block->children.size() && current_block->children[assign_idx] != current_block_child)
954 assign_idx++;
955 log_assert(assign_idx < current_block->children.size());
956 current_block->children.insert(current_block->children.begin()+assign_idx, assign);
957 wire->is_reg = true;
958 }
959 else
960 {
961 AstNode *proc = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
962 proc->children[0]->children.push_back(assign);
963 current_ast_mod->children.push_back(proc);
964 }
965
966 newNode = new AstNode(AST_IDENTIFIER, children[1]->clone());
967 newNode->str = wire_id;
968 newNode->id2ast = wire;
969 goto apply_newNode;
970 }
971
972 if (type == AST_WHILE)
973 log_error("While loops are only allowed in constant functions at %s:%d!\n", filename.c_str(), linenum);
974
975 if (type == AST_REPEAT)
976 log_error("Repeat loops are only allowed in constant functions at %s:%d!\n", filename.c_str(), linenum);
977
978 // unroll for loops and generate-for blocks
979 if ((type == AST_GENFOR || type == AST_FOR) && children.size() != 0)
980 {
981 AstNode *init_ast = children[0];
982 AstNode *while_ast = children[1];
983 AstNode *next_ast = children[2];
984 AstNode *body_ast = children[3];
985
986 while (body_ast->type == AST_GENBLOCK && body_ast->str.empty() &&
987 body_ast->children.size() == 1 && body_ast->children.at(0)->type == AST_GENBLOCK)
988 body_ast = body_ast->children.at(0);
989
990 if (init_ast->type != AST_ASSIGN_EQ)
991 log_error("Unsupported 1st expression of generate for-loop at %s:%d!\n", filename.c_str(), linenum);
992 if (next_ast->type != AST_ASSIGN_EQ)
993 log_error("Unsupported 3rd expression of generate for-loop at %s:%d!\n", filename.c_str(), linenum);
994
995 if (type == AST_GENFOR) {
996 if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_GENVAR)
997 log_error("Left hand side of 1st expression of generate for-loop at %s:%d is not a gen var!\n", filename.c_str(), linenum);
998 if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_GENVAR)
999 log_error("Left hand side of 3rd expression of generate for-loop at %s:%d is not a gen var!\n", filename.c_str(), linenum);
1000 } else {
1001 if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_WIRE)
1002 log_error("Left hand side of 1st expression of generate for-loop at %s:%d is not a register!\n", filename.c_str(), linenum);
1003 if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_WIRE)
1004 log_error("Left hand side of 3rd expression of generate for-loop at %s:%d is not a register!\n", filename.c_str(), linenum);
1005 }
1006
1007 if (init_ast->children[0]->id2ast != next_ast->children[0]->id2ast)
1008 log_error("Incompatible left-hand sides in 1st and 3rd expression of generate for-loop at %s:%d!\n", filename.c_str(), linenum);
1009
1010 // eval 1st expression
1011 AstNode *varbuf = init_ast->children[1]->clone();
1012 while (varbuf->simplify(true, false, false, stage, 32, true, false)) { }
1013
1014 if (varbuf->type != AST_CONSTANT)
1015 log_error("Right hand side of 1st expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum);
1016
1017 varbuf = new AstNode(AST_LOCALPARAM, varbuf);
1018 varbuf->str = init_ast->children[0]->str;
1019
1020 AstNode *backup_scope_varbuf = current_scope[varbuf->str];
1021 current_scope[varbuf->str] = varbuf;
1022
1023 size_t current_block_idx = 0;
1024 if (type == AST_FOR) {
1025 while (current_block_idx < current_block->children.size() &&
1026 current_block->children[current_block_idx] != current_block_child)
1027 current_block_idx++;
1028 }
1029
1030 while (1)
1031 {
1032 // eval 2nd expression
1033 AstNode *buf = while_ast->clone();
1034 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1035
1036 if (buf->type != AST_CONSTANT)
1037 log_error("2nd expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum);
1038
1039 if (buf->integer == 0) {
1040 delete buf;
1041 break;
1042 }
1043 delete buf;
1044
1045 // expand body
1046 int index = varbuf->children[0]->integer;
1047 if (body_ast->type == AST_GENBLOCK)
1048 buf = body_ast->clone();
1049 else
1050 buf = new AstNode(AST_GENBLOCK, body_ast->clone());
1051 if (buf->str.empty()) {
1052 std::stringstream sstr;
1053 sstr << "$genblock$" << filename << ":" << linenum << "$" << (autoidx++);
1054 buf->str = sstr.str();
1055 }
1056 std::map<std::string, std::string> name_map;
1057 std::stringstream sstr;
1058 sstr << buf->str << "[" << index << "].";
1059 buf->expand_genblock(varbuf->str, sstr.str(), name_map);
1060
1061 if (type == AST_GENFOR) {
1062 for (size_t i = 0; i < buf->children.size(); i++) {
1063 buf->children[i]->simplify(false, false, false, stage, -1, false, false);
1064 current_ast_mod->children.push_back(buf->children[i]);
1065 }
1066 } else {
1067 for (size_t i = 0; i < buf->children.size(); i++)
1068 current_block->children.insert(current_block->children.begin() + current_block_idx++, buf->children[i]);
1069 }
1070 buf->children.clear();
1071 delete buf;
1072
1073 // eval 3rd expression
1074 buf = next_ast->children[1]->clone();
1075 while (buf->simplify(true, false, false, stage, 32, true, false)) { }
1076
1077 if (buf->type != AST_CONSTANT)
1078 log_error("Right hand side of 3rd expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum);
1079
1080 delete varbuf->children[0];
1081 varbuf->children[0] = buf;
1082 }
1083
1084 current_scope[varbuf->str] = backup_scope_varbuf;
1085 delete varbuf;
1086 delete_children();
1087 did_something = true;
1088 }
1089
1090 // check for local objects in unnamed block
1091 if (type == AST_BLOCK && str.empty())
1092 {
1093 for (size_t i = 0; i < children.size(); i++)
1094 if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM)
1095 log_error("Local declaration in unnamed block at %s:%d is an unsupported SystemVerilog feature!\n",
1096 children[i]->filename.c_str(), children[i]->linenum);
1097 }
1098
1099 // transform block with name
1100 if (type == AST_BLOCK && !str.empty())
1101 {
1102 std::map<std::string, std::string> name_map;
1103 expand_genblock(std::string(), str + ".", name_map);
1104
1105 std::vector<AstNode*> new_children;
1106 for (size_t i = 0; i < children.size(); i++)
1107 if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM) {
1108 children[i]->simplify(false, false, false, stage, -1, false, false);
1109 current_ast_mod->children.push_back(children[i]);
1110 current_scope[children[i]->str] = children[i];
1111 } else
1112 new_children.push_back(children[i]);
1113
1114 children.swap(new_children);
1115 did_something = true;
1116 str.clear();
1117 }
1118
1119 // simplify unconditional generate block
1120 if (type == AST_GENBLOCK && children.size() != 0)
1121 {
1122 if (!str.empty()) {
1123 std::map<std::string, std::string> name_map;
1124 expand_genblock(std::string(), str + ".", name_map);
1125 }
1126
1127 for (size_t i = 0; i < children.size(); i++) {
1128 children[i]->simplify(false, false, false, stage, -1, false, false);
1129 current_ast_mod->children.push_back(children[i]);
1130 }
1131
1132 children.clear();
1133 did_something = true;
1134 }
1135
1136 // simplify generate-if blocks
1137 if (type == AST_GENIF && children.size() != 0)
1138 {
1139 AstNode *buf = children[0]->clone();
1140 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1141 if (buf->type != AST_CONSTANT) {
1142 // for (auto f : log_files)
1143 // dumpAst(f, "verilog-ast> ");
1144 log_error("Condition for generate if at %s:%d is not constant!\n", filename.c_str(), linenum);
1145 }
1146 if (buf->asBool() != 0) {
1147 delete buf;
1148 buf = children[1]->clone();
1149 } else {
1150 delete buf;
1151 buf = children.size() > 2 ? children[2]->clone() : NULL;
1152 }
1153
1154 if (buf)
1155 {
1156 if (buf->type != AST_GENBLOCK)
1157 buf = new AstNode(AST_GENBLOCK, buf);
1158
1159 if (!buf->str.empty()) {
1160 std::map<std::string, std::string> name_map;
1161 buf->expand_genblock(std::string(), buf->str + ".", name_map);
1162 }
1163
1164 for (size_t i = 0; i < buf->children.size(); i++) {
1165 buf->children[i]->simplify(false, false, false, stage, -1, false, false);
1166 current_ast_mod->children.push_back(buf->children[i]);
1167 }
1168
1169 buf->children.clear();
1170 delete buf;
1171 }
1172
1173 delete_children();
1174 did_something = true;
1175 }
1176
1177 // simplify generate-case blocks
1178 if (type == AST_GENCASE && children.size() != 0)
1179 {
1180 AstNode *buf = children[0]->clone();
1181 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1182 if (buf->type != AST_CONSTANT) {
1183 // for (auto f : log_files)
1184 // dumpAst(f, "verilog-ast> ");
1185 log_error("Condition for generate case at %s:%d is not constant!\n", filename.c_str(), linenum);
1186 }
1187
1188 bool ref_signed = buf->is_signed;
1189 RTLIL::Const ref_value = buf->bitsAsConst();
1190 delete buf;
1191
1192 AstNode *selected_case = NULL;
1193 for (size_t i = 1; i < children.size(); i++)
1194 {
1195 log_assert(children.at(i)->type == AST_COND || children.at(i)->type == AST_CONDX || children.at(i)->type == AST_CONDZ);
1196
1197 AstNode *this_genblock = NULL;
1198 for (auto child : children.at(i)->children) {
1199 log_assert(this_genblock == NULL);
1200 if (child->type == AST_GENBLOCK)
1201 this_genblock = child;
1202 }
1203
1204 for (auto child : children.at(i)->children)
1205 {
1206 if (child->type == AST_DEFAULT) {
1207 if (selected_case == NULL)
1208 selected_case = this_genblock;
1209 continue;
1210 }
1211 if (child->type == AST_GENBLOCK)
1212 continue;
1213
1214 buf = child->clone();
1215 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1216 if (buf->type != AST_CONSTANT) {
1217 // for (auto f : log_files)
1218 // dumpAst(f, "verilog-ast> ");
1219 log_error("Expression in generate case at %s:%d is not constant!\n", filename.c_str(), linenum);
1220 }
1221
1222 bool is_selected = RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool();
1223 delete buf;
1224
1225 if (is_selected) {
1226 selected_case = this_genblock;
1227 i = children.size();
1228 break;
1229 }
1230 }
1231 }
1232
1233 if (selected_case != NULL)
1234 {
1235 log_assert(selected_case->type == AST_GENBLOCK);
1236 buf = selected_case->clone();
1237
1238 if (!buf->str.empty()) {
1239 std::map<std::string, std::string> name_map;
1240 buf->expand_genblock(std::string(), buf->str + ".", name_map);
1241 }
1242
1243 for (size_t i = 0; i < buf->children.size(); i++) {
1244 buf->children[i]->simplify(false, false, false, stage, -1, false, false);
1245 current_ast_mod->children.push_back(buf->children[i]);
1246 }
1247
1248 buf->children.clear();
1249 delete buf;
1250 }
1251
1252 delete_children();
1253 did_something = true;
1254 }
1255
1256 // unroll cell arrays
1257 if (type == AST_CELLARRAY)
1258 {
1259 if (!children.at(0)->range_valid)
1260 log_error("Non-constant array range on cell array at %s:%d.\n", filename.c_str(), linenum);
1261
1262 newNode = new AstNode(AST_GENBLOCK);
1263 int num = max(children.at(0)->range_left, children.at(0)->range_right) - min(children.at(0)->range_left, children.at(0)->range_right) + 1;
1264
1265 for (int i = 0; i < num; i++) {
1266 int idx = children.at(0)->range_left > children.at(0)->range_right ? children.at(0)->range_right + i : children.at(0)->range_right - i;
1267 AstNode *new_cell = children.at(1)->clone();
1268 newNode->children.push_back(new_cell);
1269 new_cell->str += stringf("[%d]", idx);
1270 if (new_cell->type == AST_PRIMITIVE) {
1271 log_error("Cell arrays of primitives are currently not supported at %s:%d.\n", filename.c_str(), linenum);
1272 } else {
1273 log_assert(new_cell->children.at(0)->type == AST_CELLTYPE);
1274 new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str.c_str());
1275 }
1276 }
1277
1278 goto apply_newNode;
1279 }
1280
1281 // replace primitives with assignments
1282 if (type == AST_PRIMITIVE)
1283 {
1284 if (children.size() < 2)
1285 log_error("Insufficient number of arguments for primitive `%s' at %s:%d!\n",
1286 str.c_str(), filename.c_str(), linenum);
1287
1288 std::vector<AstNode*> children_list;
1289 for (auto child : children) {
1290 log_assert(child->type == AST_ARGUMENT);
1291 log_assert(child->children.size() == 1);
1292 children_list.push_back(child->children[0]);
1293 child->children.clear();
1294 delete child;
1295 }
1296 children.clear();
1297
1298 if (str == "bufif0" || str == "bufif1" || str == "notif0" || str == "notif1")
1299 {
1300 if (children_list.size() != 3)
1301 log_error("Invalid number of arguments for primitive `%s' at %s:%d!\n",
1302 str.c_str(), filename.c_str(), linenum);
1303
1304 std::vector<RTLIL::State> z_const(1, RTLIL::State::Sz);
1305
1306 AstNode *mux_input = children_list.at(1);
1307 if (str == "notif0" || str == "notif1") {
1308 mux_input = new AstNode(AST_BIT_NOT, mux_input);
1309 }
1310 AstNode *node = new AstNode(AST_TERNARY, children_list.at(2));
1311 if (str == "bufif0") {
1312 node->children.push_back(AstNode::mkconst_bits(z_const, false));
1313 node->children.push_back(mux_input);
1314 } else {
1315 node->children.push_back(mux_input);
1316 node->children.push_back(AstNode::mkconst_bits(z_const, false));
1317 }
1318
1319 str.clear();
1320 type = AST_ASSIGN;
1321 children.push_back(children_list.at(0));
1322 children.push_back(node);
1323 did_something = true;
1324 }
1325 else
1326 {
1327 AstNodeType op_type = AST_NONE;
1328 bool invert_results = false;
1329
1330 if (str == "and")
1331 op_type = AST_BIT_AND;
1332 if (str == "nand")
1333 op_type = AST_BIT_AND, invert_results = true;
1334 if (str == "or")
1335 op_type = AST_BIT_OR;
1336 if (str == "nor")
1337 op_type = AST_BIT_OR, invert_results = true;
1338 if (str == "xor")
1339 op_type = AST_BIT_XOR;
1340 if (str == "xnor")
1341 op_type = AST_BIT_XOR, invert_results = true;
1342 if (str == "buf")
1343 op_type = AST_POS;
1344 if (str == "not")
1345 op_type = AST_POS, invert_results = true;
1346 log_assert(op_type != AST_NONE);
1347
1348 AstNode *node = children_list[1];
1349 if (op_type != AST_POS)
1350 for (size_t i = 2; i < children_list.size(); i++)
1351 node = new AstNode(op_type, node, children_list[i]);
1352 if (invert_results)
1353 node = new AstNode(AST_BIT_NOT, node);
1354
1355 str.clear();
1356 type = AST_ASSIGN;
1357 children.push_back(children_list[0]);
1358 children.push_back(node);
1359 did_something = true;
1360 }
1361 }
1362
1363 // replace dynamic ranges in left-hand side expressions (e.g. "foo[bar] <= 1'b1;") with
1364 // a big case block that selects the correct single-bit assignment.
1365 if (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) {
1366 if (children[0]->type != AST_IDENTIFIER || children[0]->children.size() == 0)
1367 goto skip_dynamic_range_lvalue_expansion;
1368 if (children[0]->children[0]->range_valid || did_something)
1369 goto skip_dynamic_range_lvalue_expansion;
1370 if (children[0]->id2ast == NULL || children[0]->id2ast->type != AST_WIRE)
1371 goto skip_dynamic_range_lvalue_expansion;
1372 if (!children[0]->id2ast->range_valid)
1373 goto skip_dynamic_range_lvalue_expansion;
1374 int source_width = children[0]->id2ast->range_left - children[0]->id2ast->range_right + 1;
1375 int result_width = 1;
1376 AstNode *shift_expr = NULL;
1377 AstNode *range = children[0]->children[0];
1378 if (range->children.size() == 1) {
1379 shift_expr = range->children[0]->clone();
1380 } else {
1381 shift_expr = range->children[1]->clone();
1382 AstNode *left_at_zero_ast = range->children[0]->clone();
1383 AstNode *right_at_zero_ast = range->children[1]->clone();
1384 while (left_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { }
1385 while (right_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { }
1386 if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
1387 log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n",
1388 str.c_str(), filename.c_str(), linenum);
1389 result_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1;
1390 }
1391 did_something = true;
1392 newNode = new AstNode(AST_CASE, shift_expr);
1393 for (int i = 0; i <= source_width-result_width; i++) {
1394 int start_bit = children[0]->id2ast->range_right + i;
1395 AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit, true));
1396 AstNode *lvalue = children[0]->clone();
1397 lvalue->delete_children();
1398 lvalue->children.push_back(new AstNode(AST_RANGE,
1399 mkconst_int(start_bit+result_width-1, true), mkconst_int(start_bit, true)));
1400 cond->children.push_back(new AstNode(AST_BLOCK, new AstNode(type, lvalue, children[1]->clone())));
1401 newNode->children.push_back(cond);
1402 }
1403 goto apply_newNode;
1404 }
1405 skip_dynamic_range_lvalue_expansion:;
1406
1407 if (stage > 1 && (type == AST_ASSERT || type == AST_ASSUME || type == AST_LIVE || type == AST_FAIR || type == AST_COVER) && current_block != NULL)
1408 {
1409 std::stringstream sstr;
1410 sstr << "$formal$" << filename << ":" << linenum << "$" << (autoidx++);
1411 std::string id_check = sstr.str() + "_CHECK", id_en = sstr.str() + "_EN";
1412
1413 AstNode *wire_check = new AstNode(AST_WIRE);
1414 wire_check->str = id_check;
1415 current_ast_mod->children.push_back(wire_check);
1416 current_scope[wire_check->str] = wire_check;
1417 while (wire_check->simplify(true, false, false, 1, -1, false, false)) { }
1418
1419 AstNode *wire_en = new AstNode(AST_WIRE);
1420 wire_en->str = id_en;
1421 current_ast_mod->children.push_back(wire_en);
1422 if (current_always_clocked) {
1423 current_ast_mod->children.push_back(new AstNode(AST_INITIAL, new AstNode(AST_BLOCK, new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), AstNode::mkconst_int(0, false, 1)))));
1424 current_ast_mod->children.back()->children[0]->children[0]->children[0]->str = id_en;
1425 }
1426 current_scope[wire_en->str] = wire_en;
1427 while (wire_en->simplify(true, false, false, 1, -1, false, false)) { }
1428
1429 std::vector<RTLIL::State> x_bit;
1430 x_bit.push_back(RTLIL::State::Sx);
1431
1432 AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bit, false));
1433 assign_check->children[0]->str = id_check;
1434
1435 AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, 1));
1436 assign_en->children[0]->str = id_en;
1437
1438 AstNode *default_signals = new AstNode(AST_BLOCK);
1439 default_signals->children.push_back(assign_check);
1440 default_signals->children.push_back(assign_en);
1441 current_top_block->children.insert(current_top_block->children.begin(), default_signals);
1442
1443 assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone()));
1444 assign_check->children[0]->str = id_check;
1445
1446 if (current_always == nullptr || current_always->type != AST_INITIAL) {
1447 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(1, false, 1));
1448 } else {
1449 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_FCALL));
1450 assign_en->children[1]->str = "\\$initstate";
1451 }
1452 assign_en->children[0]->str = id_en;
1453
1454 newNode = new AstNode(AST_BLOCK);
1455 newNode->children.push_back(assign_check);
1456 newNode->children.push_back(assign_en);
1457
1458 AstNode *assertnode = new AstNode(type);
1459 assertnode->children.push_back(new AstNode(AST_IDENTIFIER));
1460 assertnode->children.push_back(new AstNode(AST_IDENTIFIER));
1461 assertnode->children[0]->str = id_check;
1462 assertnode->children[1]->str = id_en;
1463 assertnode->attributes.swap(attributes);
1464 current_ast_mod->children.push_back(assertnode);
1465
1466 goto apply_newNode;
1467 }
1468
1469 if (stage > 1 && (type == AST_ASSERT || type == AST_ASSUME || type == AST_LIVE || type == AST_FAIR || type == AST_COVER) && children.size() == 1)
1470 {
1471 children.push_back(mkconst_int(1, false, 1));
1472 did_something = true;
1473 }
1474
1475 // found right-hand side identifier for memory -> replace with memory read port
1476 if (stage > 1 && type == AST_IDENTIFIER && id2ast != NULL && id2ast->type == AST_MEMORY && !in_lvalue &&
1477 children.size() == 1 && children[0]->type == AST_RANGE && children[0]->children.size() == 1) {
1478 newNode = new AstNode(AST_MEMRD, children[0]->children[0]->clone());
1479 newNode->str = str;
1480 newNode->id2ast = id2ast;
1481 goto apply_newNode;
1482 }
1483
1484 // assignment with nontrivial member in left-hand concat expression -> split assignment
1485 if ((type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) && children[0]->type == AST_CONCAT && width_hint > 0)
1486 {
1487 bool found_nontrivial_member = false;
1488
1489 for (auto child : children[0]->children) {
1490 if (child->type == AST_IDENTIFIER && child->id2ast != NULL && child->id2ast->type == AST_MEMORY)
1491 found_nontrivial_member = true;
1492 }
1493
1494 if (found_nontrivial_member)
1495 {
1496 newNode = new AstNode(AST_BLOCK);
1497
1498 AstNode *wire_tmp = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(width_hint-1, true), mkconst_int(0, true)));
1499 wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", filename.c_str(), linenum, autoidx++);
1500 current_ast_mod->children.push_back(wire_tmp);
1501 current_scope[wire_tmp->str] = wire_tmp;
1502 wire_tmp->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
1503 while (wire_tmp->simplify(true, false, false, 1, -1, false, false)) { }
1504
1505 AstNode *wire_tmp_id = new AstNode(AST_IDENTIFIER);
1506 wire_tmp_id->str = wire_tmp->str;
1507
1508 newNode->children.push_back(new AstNode(AST_ASSIGN_EQ, wire_tmp_id, children[1]->clone()));
1509
1510 int cursor = 0;
1511 for (auto child : children[0]->children)
1512 {
1513 int child_width_hint = -1;
1514 bool child_sign_hint = true;
1515 child->detectSignWidth(child_width_hint, child_sign_hint);
1516
1517 AstNode *rhs = wire_tmp_id->clone();
1518 rhs->children.push_back(new AstNode(AST_RANGE, AstNode::mkconst_int(cursor+child_width_hint-1, true), AstNode::mkconst_int(cursor, true)));
1519 newNode->children.push_back(new AstNode(type, child->clone(), rhs));
1520
1521 cursor += child_width_hint;
1522 }
1523
1524 goto apply_newNode;
1525 }
1526 }
1527
1528 // assignment with memory in left-hand side expression -> replace with memory write port
1529 if (stage > 1 && (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) && children[0]->type == AST_IDENTIFIER &&
1530 children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY && children[0]->id2ast->children.size() >= 2 &&
1531 children[0]->id2ast->children[0]->range_valid && children[0]->id2ast->children[1]->range_valid &&
1532 (children[0]->children.size() == 1 || children[0]->children.size() == 2) && children[0]->children[0]->type == AST_RANGE)
1533 {
1534 std::stringstream sstr;
1535 sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++);
1536 std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA", id_en = sstr.str() + "_EN";
1537
1538 if (type == AST_ASSIGN_EQ) {
1539 pair<string, int> this_blocking_assignment_warn(filename, linenum);
1540 if (this_blocking_assignment_warn != last_blocking_assignment_warn)
1541 log_warning("Blocking assignment to memory in line %s:%d is handled like a non-blocking assignment.\n",
1542 filename.c_str(), linenum);
1543 last_blocking_assignment_warn = this_blocking_assignment_warn;
1544 }
1545
1546 int mem_width, mem_size, addr_bits;
1547 bool mem_signed = children[0]->id2ast->is_signed;
1548 children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
1549
1550 int data_range_left = children[0]->id2ast->children[0]->range_left;
1551 int data_range_right = children[0]->id2ast->children[0]->range_right;
1552 int mem_data_range_offset = std::min(data_range_left, data_range_right);
1553
1554 int addr_width_hint = -1;
1555 bool addr_sign_hint = true;
1556 children[0]->children[0]->children[0]->detectSignWidthWorker(addr_width_hint, addr_sign_hint);
1557 addr_bits = std::max(addr_bits, addr_width_hint);
1558
1559 AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
1560 wire_addr->str = id_addr;
1561 current_ast_mod->children.push_back(wire_addr);
1562 current_scope[wire_addr->str] = wire_addr;
1563 while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
1564
1565 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
1566 wire_data->str = id_data;
1567 wire_data->is_signed = mem_signed;
1568 current_ast_mod->children.push_back(wire_data);
1569 current_scope[wire_data->str] = wire_data;
1570 while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
1571
1572 AstNode *wire_en = nullptr;
1573 if (current_always->type != AST_INITIAL) {
1574 wire_en = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
1575 wire_en->str = id_en;
1576 current_ast_mod->children.push_back(wire_en);
1577 current_scope[wire_en->str] = wire_en;
1578 while (wire_en->simplify(true, false, false, 1, -1, false, false)) { }
1579 }
1580
1581 std::vector<RTLIL::State> x_bits_addr, x_bits_data, set_bits_en;
1582 for (int i = 0; i < addr_bits; i++)
1583 x_bits_addr.push_back(RTLIL::State::Sx);
1584 for (int i = 0; i < mem_width; i++)
1585 x_bits_data.push_back(RTLIL::State::Sx);
1586 for (int i = 0; i < mem_width; i++)
1587 set_bits_en.push_back(RTLIL::State::S1);
1588
1589 AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false));
1590 assign_addr->children[0]->str = id_addr;
1591
1592 AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false));
1593 assign_data->children[0]->str = id_data;
1594
1595 AstNode *assign_en = nullptr;
1596 if (current_always->type != AST_INITIAL) {
1597 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width));
1598 assign_en->children[0]->str = id_en;
1599 }
1600
1601 AstNode *default_signals = new AstNode(AST_BLOCK);
1602 default_signals->children.push_back(assign_addr);
1603 default_signals->children.push_back(assign_data);
1604 if (current_always->type != AST_INITIAL)
1605 default_signals->children.push_back(assign_en);
1606 current_top_block->children.insert(current_top_block->children.begin(), default_signals);
1607
1608 assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());
1609 assign_addr->children[0]->str = id_addr;
1610
1611 if (children[0]->children.size() == 2)
1612 {
1613 if (children[0]->children[1]->range_valid)
1614 {
1615 int offset = children[0]->children[1]->range_right;
1616 int width = children[0]->children[1]->range_left - offset + 1;
1617 offset -= mem_data_range_offset;
1618
1619 std::vector<RTLIL::State> padding_x(offset, RTLIL::State::Sx);
1620
1621 assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),
1622 new AstNode(AST_CONCAT, mkconst_bits(padding_x, false), children[1]->clone()));
1623 assign_data->children[0]->str = id_data;
1624
1625 if (current_always->type != AST_INITIAL) {
1626 for (int i = 0; i < mem_width; i++)
1627 set_bits_en[i] = offset <= i && i < offset+width ? RTLIL::State::S1 : RTLIL::State::S0;
1628 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));
1629 assign_en->children[0]->str = id_en;
1630 }
1631 }
1632 else
1633 {
1634 AstNode *the_range = children[0]->children[1];
1635 AstNode *left_at_zero_ast = the_range->children[0]->clone();
1636 AstNode *right_at_zero_ast = the_range->children.size() >= 2 ? the_range->children[1]->clone() : left_at_zero_ast->clone();
1637 AstNode *offset_ast = right_at_zero_ast->clone();
1638
1639 if (mem_data_range_offset)
1640 offset_ast = new AstNode(AST_SUB, offset_ast, mkconst_int(mem_data_range_offset, true));
1641
1642 while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }
1643 while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }
1644 if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
1645 log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum);
1646 int width = left_at_zero_ast->integer - right_at_zero_ast->integer + 1;
1647
1648 assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),
1649 new AstNode(AST_SHIFT_LEFT, children[1]->clone(), offset_ast->clone()));
1650 assign_data->children[0]->str = id_data;
1651
1652 if (current_always->type != AST_INITIAL) {
1653 for (int i = 0; i < mem_width; i++)
1654 set_bits_en[i] = i < width ? RTLIL::State::S1 : RTLIL::State::S0;
1655 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),
1656 new AstNode(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone()));
1657 assign_en->children[0]->str = id_en;
1658 }
1659
1660 delete left_at_zero_ast;
1661 delete right_at_zero_ast;
1662 delete offset_ast;
1663 }
1664 }
1665 else
1666 {
1667 assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone());
1668 assign_data->children[0]->str = id_data;
1669
1670 if (current_always->type != AST_INITIAL) {
1671 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));
1672 assign_en->children[0]->str = id_en;
1673 }
1674 }
1675
1676 newNode = new AstNode(AST_BLOCK);
1677 newNode->children.push_back(assign_addr);
1678 newNode->children.push_back(assign_data);
1679 if (current_always->type != AST_INITIAL)
1680 newNode->children.push_back(assign_en);
1681
1682 AstNode *wrnode = new AstNode(current_always->type == AST_INITIAL ? AST_MEMINIT : AST_MEMWR);
1683 wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
1684 wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
1685 if (current_always->type != AST_INITIAL)
1686 wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
1687 else
1688 wrnode->children.push_back(AstNode::mkconst_int(1, false));
1689 wrnode->str = children[0]->str;
1690 wrnode->id2ast = children[0]->id2ast;
1691 wrnode->children[0]->str = id_addr;
1692 wrnode->children[1]->str = id_data;
1693 if (current_always->type != AST_INITIAL)
1694 wrnode->children[2]->str = id_en;
1695 current_ast_mod->children.push_back(wrnode);
1696
1697 goto apply_newNode;
1698 }
1699
1700 // replace function and task calls with the code from the function or task
1701 if ((type == AST_FCALL || type == AST_TCALL) && !str.empty())
1702 {
1703 if (type == AST_FCALL)
1704 {
1705 if (str == "\\$initstate")
1706 {
1707 int myidx = autoidx++;
1708
1709 AstNode *wire = new AstNode(AST_WIRE);
1710 wire->str = stringf("$initstate$%d_wire", myidx);
1711 current_ast_mod->children.push_back(wire);
1712 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
1713
1714 AstNode *cell = new AstNode(AST_CELL, new AstNode(AST_CELLTYPE), new AstNode(AST_ARGUMENT, new AstNode(AST_IDENTIFIER)));
1715 cell->str = stringf("$initstate$%d", myidx);
1716 cell->children[0]->str = "$initstate";
1717 cell->children[1]->str = "\\Y";
1718 cell->children[1]->children[0]->str = wire->str;
1719 cell->children[1]->children[0]->id2ast = wire;
1720 current_ast_mod->children.push_back(cell);
1721 while (cell->simplify(true, false, false, 1, -1, false, false)) { }
1722
1723 newNode = new AstNode(AST_IDENTIFIER);
1724 newNode->str = wire->str;
1725 newNode->id2ast = wire;
1726 goto apply_newNode;
1727 }
1728
1729 if (str == "\\$past")
1730 {
1731 if (width_hint <= 0)
1732 goto replace_fcall_later;
1733
1734 int num_steps = 1;
1735
1736 if (GetSize(children) != 1 && GetSize(children) != 2)
1737 log_error("System function %s got %d arguments, expected 1 or 2 at %s:%d.\n",
1738 RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum);
1739
1740 if (!current_always_clocked)
1741 log_error("System function %s is only allowed in clocked blocks at %s:%d.\n",
1742 RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum);
1743
1744 if (GetSize(children) == 2)
1745 {
1746 AstNode *buf = children[1]->clone();
1747 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1748 if (buf->type != AST_CONSTANT)
1749 log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
1750
1751 num_steps = buf->asInt(true);
1752 delete buf;
1753 }
1754
1755 AstNode *block = nullptr;
1756
1757 for (auto child : current_always->children)
1758 if (child->type == AST_BLOCK)
1759 block = child;
1760
1761 log_assert(block != nullptr);
1762
1763 int myidx = autoidx++;
1764 AstNode *outreg = nullptr;
1765
1766 for (int i = 0; i < num_steps; i++)
1767 {
1768 AstNode *reg = new AstNode(AST_WIRE, new AstNode(AST_RANGE,
1769 mkconst_int(width_hint-1, true), mkconst_int(0, true)));
1770
1771 reg->str = stringf("$past$%s:%d$%d$%d", filename.c_str(), linenum, myidx, i);
1772 reg->is_reg = true;
1773
1774 current_ast_mod->children.push_back(reg);
1775
1776 while (reg->simplify(true, false, false, 1, -1, false, false)) { }
1777
1778 AstNode *regid = new AstNode(AST_IDENTIFIER);
1779 regid->str = reg->str;
1780 regid->id2ast = reg;
1781
1782 AstNode *rhs = nullptr;
1783
1784 if (outreg == nullptr) {
1785 rhs = children.at(0)->clone();
1786 } else {
1787 rhs = new AstNode(AST_IDENTIFIER);
1788 rhs->str = outreg->str;
1789 rhs->id2ast = outreg;
1790 }
1791
1792 block->children.push_back(new AstNode(AST_ASSIGN_LE, regid, rhs));
1793 outreg = reg;
1794 }
1795
1796 newNode = new AstNode(AST_IDENTIFIER);
1797 newNode->str = outreg->str;
1798 newNode->id2ast = outreg;
1799 goto apply_newNode;
1800 }
1801
1802 if (str == "\\$stable" || str == "\\$rose" || str == "\\$fell")
1803 {
1804 if (GetSize(children) != 1)
1805 log_error("System function %s got %d arguments, expected 1 at %s:%d.\n",
1806 RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum);
1807
1808 if (!current_always_clocked)
1809 log_error("System function %s is only allowed in clocked blocks at %s:%d.\n",
1810 RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum);
1811
1812 AstNode *present = children.at(0)->clone();
1813 AstNode *past = clone();
1814 past->str = "\\$past";
1815
1816 if (str == "\\$stable")
1817 newNode = new AstNode(AST_EQ, past, present);
1818
1819 else if (str == "\\$rose")
1820 newNode = new AstNode(AST_LOGIC_AND, new AstNode(AST_LOGIC_NOT, past), present);
1821
1822 else if (str == "\\$fell")
1823 newNode = new AstNode(AST_LOGIC_AND, past, new AstNode(AST_LOGIC_NOT, present));
1824
1825 else
1826 log_abort();
1827
1828 goto apply_newNode;
1829 }
1830
1831 if (str == "\\$rose" || str == "\\$fell")
1832 {
1833 if (GetSize(children) != 1)
1834 log_error("System function %s got %d arguments, expected 1 at %s:%d.\n",
1835 RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum);
1836
1837 if (!current_always_clocked)
1838 log_error("System function %s is only allowed in clocked blocks at %s:%d.\n",
1839 RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum);
1840
1841 newNode = new AstNode(AST_EQ, children.at(0)->clone(), clone());
1842 newNode->children.at(1)->str = "\\$past";
1843 goto apply_newNode;
1844 }
1845
1846 // $anyconst and $anyseq are mapped in AstNode::genRTLIL()
1847 if (str == "\\$anyconst" || str == "\\$anyseq") {
1848 recursion_counter--;
1849 return false;
1850 }
1851
1852 if (str == "\\$clog2")
1853 {
1854 if (children.size() != 1)
1855 log_error("System function %s got %d arguments, expected 1 at %s:%d.\n",
1856 RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum);
1857
1858 AstNode *buf = children[0]->clone();
1859 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1860 if (buf->type != AST_CONSTANT)
1861 log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
1862
1863 RTLIL::Const arg_value = buf->bitsAsConst();
1864 if (arg_value.as_bool())
1865 arg_value = const_sub(arg_value, 1, false, false, GetSize(arg_value));
1866 delete buf;
1867
1868 uint32_t result = 0;
1869 for (size_t i = 0; i < arg_value.bits.size(); i++)
1870 if (arg_value.bits.at(i) == RTLIL::State::S1)
1871 result = i + 1;
1872
1873 newNode = mkconst_int(result, false);
1874 goto apply_newNode;
1875 }
1876
1877 if (str == "\\$size" || str == "\\$bits")
1878 {
1879 if (str == "\\$bits" && children.size() != 1)
1880 log_error("System function %s got %d arguments, expected 1 at %s:%d.\n",
1881 RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum);
1882
1883 if (str == "\\$size" && children.size() != 1 && children.size() != 2)
1884 log_error("System function %s got %d arguments, expected 1 or 2 at %s:%d.\n",
1885 RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum);
1886
1887 int dim = 1;
1888 if (str == "\\$size" && children.size() == 2) {
1889 AstNode *buf = children[1]->clone();
1890 // Evaluate constant expression
1891 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1892 dim = buf->asInt(false);
1893 delete buf;
1894 }
1895 AstNode *buf = children[0]->clone();
1896 int mem_depth = 1;
1897 AstNode *id_ast = NULL;
1898
1899 // Is this needed?
1900 //while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1901 buf->detectSignWidth(width_hint, sign_hint);
1902
1903 if (buf->type == AST_IDENTIFIER) {
1904 id_ast = buf->id2ast;
1905 if (id_ast == NULL && current_scope.count(buf->str))
1906 id_ast = current_scope.at(buf->str);
1907 if (!id_ast)
1908 log_error("Failed to resolve identifier %s for width detection at %s:%d!\n", buf->str.c_str(), filename.c_str(), linenum);
1909 if (id_ast->type == AST_MEMORY) {
1910 // We got here only if the argument is a memory
1911 // Otherwise $size() and $bits() return the expression width
1912 AstNode *mem_range = id_ast->children[1];
1913 if (str == "\\$bits") {
1914 if (mem_range->type == AST_RANGE) {
1915 if (!mem_range->range_valid)
1916 log_error("Failed to detect width of memory access `%s' at %s:%d!\n", buf->str.c_str(), filename.c_str(), linenum);
1917 mem_depth = mem_range->range_left - mem_range->range_right + 1;
1918 } else
1919 log_error("Unknown memory depth AST type in `%s' at %s:%d!\n", buf->str.c_str(), filename.c_str(), linenum);
1920 } else {
1921 // $size()
1922 if (mem_range->type == AST_RANGE) {
1923 if (!mem_range->range_valid)
1924 log_error("Failed to detect width of memory access `%s' at %s:%d!\n", buf->str.c_str(), filename.c_str(), linenum);
1925 int dims;
1926 if (id_ast->multirange_dimensions.empty())
1927 dims = 1;
1928 else
1929 dims = GetSize(id_ast->multirange_dimensions)/2;
1930 if (dim == 1)
1931 width_hint = (dims > 1) ? id_ast->multirange_dimensions[1] : (mem_range->range_left - mem_range->range_right + 1);
1932 else if (dim <= dims) {
1933 width_hint = id_ast->multirange_dimensions[2*dim-1];
1934 } else if ((dim > dims+1) || (dim < 0))
1935 log_error("Dimension %d out of range in `%s', as it only has dimensions 1..%d at %s:%d!\n", dim, buf->str.c_str(), dims+1, filename.c_str(), linenum);
1936 } else
1937 log_error("Unknown memory depth AST type in `%s' at %s:%d!\n", buf->str.c_str(), filename.c_str(), linenum);
1938 }
1939 }
1940 }
1941 delete buf;
1942
1943 newNode = mkconst_int(width_hint * mem_depth, false);
1944 goto apply_newNode;
1945 }
1946
1947 if (str == "\\$ln" || str == "\\$log10" || str == "\\$exp" || str == "\\$sqrt" || str == "\\$pow" ||
1948 str == "\\$floor" || str == "\\$ceil" || str == "\\$sin" || str == "\\$cos" || str == "\\$tan" ||
1949 str == "\\$asin" || str == "\\$acos" || str == "\\$atan" || str == "\\$atan2" || str == "\\$hypot" ||
1950 str == "\\$sinh" || str == "\\$cosh" || str == "\\$tanh" || str == "\\$asinh" || str == "\\$acosh" || str == "\\$atanh" ||
1951 str == "\\$rtoi" || str == "\\$itor")
1952 {
1953 bool func_with_two_arguments = str == "\\$pow" || str == "\\$atan2" || str == "\\$hypot";
1954 double x = 0, y = 0;
1955
1956 if (func_with_two_arguments) {
1957 if (children.size() != 2)
1958 log_error("System function %s got %d arguments, expected 2 at %s:%d.\n",
1959 RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum);
1960 } else {
1961 if (children.size() != 1)
1962 log_error("System function %s got %d arguments, expected 1 at %s:%d.\n",
1963 RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum);
1964 }
1965
1966 if (children.size() >= 1) {
1967 while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1968 if (!children[0]->isConst())
1969 log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n",
1970 RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum);
1971 int child_width_hint = width_hint;
1972 bool child_sign_hint = sign_hint;
1973 children[0]->detectSignWidth(child_width_hint, child_sign_hint);
1974 x = children[0]->asReal(child_sign_hint);
1975 }
1976
1977 if (children.size() >= 2) {
1978 while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1979 if (!children[1]->isConst())
1980 log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n",
1981 RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum);
1982 int child_width_hint = width_hint;
1983 bool child_sign_hint = sign_hint;
1984 children[1]->detectSignWidth(child_width_hint, child_sign_hint);
1985 y = children[1]->asReal(child_sign_hint);
1986 }
1987
1988 if (str == "\\$rtoi") {
1989 newNode = AstNode::mkconst_int(x, true);
1990 } else {
1991 newNode = new AstNode(AST_REALVALUE);
1992 if (str == "\\$ln") newNode->realvalue = ::log(x);
1993 else if (str == "\\$log10") newNode->realvalue = ::log10(x);
1994 else if (str == "\\$exp") newNode->realvalue = ::exp(x);
1995 else if (str == "\\$sqrt") newNode->realvalue = ::sqrt(x);
1996 else if (str == "\\$pow") newNode->realvalue = ::pow(x, y);
1997 else if (str == "\\$floor") newNode->realvalue = ::floor(x);
1998 else if (str == "\\$ceil") newNode->realvalue = ::ceil(x);
1999 else if (str == "\\$sin") newNode->realvalue = ::sin(x);
2000 else if (str == "\\$cos") newNode->realvalue = ::cos(x);
2001 else if (str == "\\$tan") newNode->realvalue = ::tan(x);
2002 else if (str == "\\$asin") newNode->realvalue = ::asin(x);
2003 else if (str == "\\$acos") newNode->realvalue = ::acos(x);
2004 else if (str == "\\$atan") newNode->realvalue = ::atan(x);
2005 else if (str == "\\$atan2") newNode->realvalue = ::atan2(x, y);
2006 else if (str == "\\$hypot") newNode->realvalue = ::hypot(x, y);
2007 else if (str == "\\$sinh") newNode->realvalue = ::sinh(x);
2008 else if (str == "\\$cosh") newNode->realvalue = ::cosh(x);
2009 else if (str == "\\$tanh") newNode->realvalue = ::tanh(x);
2010 else if (str == "\\$asinh") newNode->realvalue = ::asinh(x);
2011 else if (str == "\\$acosh") newNode->realvalue = ::acosh(x);
2012 else if (str == "\\$atanh") newNode->realvalue = ::atanh(x);
2013 else if (str == "\\$itor") newNode->realvalue = x;
2014 else log_abort();
2015 }
2016 goto apply_newNode;
2017 }
2018
2019 if (current_scope.count(str) != 0 && current_scope[str]->type == AST_DPI_FUNCTION)
2020 {
2021 AstNode *dpi_decl = current_scope[str];
2022
2023 std::string rtype, fname;
2024 std::vector<std::string> argtypes;
2025 std::vector<AstNode*> args;
2026
2027 rtype = RTLIL::unescape_id(dpi_decl->children.at(0)->str);
2028 fname = RTLIL::unescape_id(dpi_decl->children.at(1)->str);
2029
2030 for (int i = 2; i < GetSize(dpi_decl->children); i++)
2031 {
2032 if (i-2 >= GetSize(children))
2033 log_error("Insufficient number of arguments in DPI function call at %s:%d.\n", filename.c_str(), linenum);
2034
2035 argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str));
2036 args.push_back(children.at(i-2)->clone());
2037 while (args.back()->simplify(true, false, false, stage, -1, false, true)) { }
2038
2039 if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE)
2040 log_error("Failed to evaluate DPI function with non-constant argument at %s:%d.\n", filename.c_str(), linenum);
2041 }
2042
2043 newNode = dpi_call(rtype, fname, argtypes, args);
2044
2045 for (auto arg : args)
2046 delete arg;
2047
2048 goto apply_newNode;
2049 }
2050
2051 if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION)
2052 log_error("Can't resolve function name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
2053 }
2054
2055 if (type == AST_TCALL)
2056 {
2057 if (str == "$finish" || str == "$stop")
2058 {
2059 if (!current_always || current_always->type != AST_INITIAL)
2060 log_error("System task `%s' outside initial block is unsupported at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
2061
2062 log_error("System task `%s' executed at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
2063 }
2064
2065 if (str == "\\$readmemh" || str == "\\$readmemb")
2066 {
2067 if (GetSize(children) < 2 || GetSize(children) > 4)
2068 log_error("System function %s got %d arguments, expected 2-4 at %s:%d.\n",
2069 RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum);
2070
2071 AstNode *node_filename = children[0]->clone();
2072 while (node_filename->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
2073 if (node_filename->type != AST_CONSTANT)
2074 log_error("Failed to evaluate system function `%s' with non-constant 1st argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
2075
2076 AstNode *node_memory = children[1]->clone();
2077 while (node_memory->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
2078 if (node_memory->type != AST_IDENTIFIER || node_memory->id2ast == nullptr || node_memory->id2ast->type != AST_MEMORY)
2079 log_error("Failed to evaluate system function `%s' with non-memory 2nd argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
2080
2081 int start_addr = -1, finish_addr = -1;
2082
2083 if (GetSize(children) > 2) {
2084 AstNode *node_addr = children[2]->clone();
2085 while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
2086 if (node_addr->type != AST_CONSTANT)
2087 log_error("Failed to evaluate system function `%s' with non-constant 3rd argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
2088 start_addr = int(node_addr->asInt(false));
2089 }
2090
2091 if (GetSize(children) > 3) {
2092 AstNode *node_addr = children[3]->clone();
2093 while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
2094 if (node_addr->type != AST_CONSTANT)
2095 log_error("Failed to evaluate system function `%s' with non-constant 4th argument at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
2096 finish_addr = int(node_addr->asInt(false));
2097 }
2098
2099 bool unconditional_init = false;
2100 if (current_always->type == AST_INITIAL) {
2101 pool<AstNode*> queue;
2102 log_assert(current_always->children[0]->type == AST_BLOCK);
2103 queue.insert(current_always->children[0]);
2104 while (!unconditional_init && !queue.empty()) {
2105 pool<AstNode*> next_queue;
2106 for (auto n : queue)
2107 for (auto c : n->children) {
2108 if (c == this)
2109 unconditional_init = true;
2110 next_queue.insert(c);
2111 }
2112 next_queue.swap(queue);
2113 }
2114 }
2115
2116 newNode = readmem(str == "\\$readmemh", node_filename->bitsAsConst().decode_string(), node_memory->id2ast, start_addr, finish_addr, unconditional_init);
2117 goto apply_newNode;
2118 }
2119
2120 if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK)
2121 log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
2122 }
2123
2124 AstNode *decl = current_scope[str];
2125
2126 std::stringstream sstr;
2127 sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++) << "$";
2128 std::string prefix = sstr.str();
2129
2130 bool recommend_const_eval = false;
2131 bool require_const_eval = in_param ? false : has_const_only_constructs(recommend_const_eval);
2132 if ((in_param || recommend_const_eval || require_const_eval) && !decl->attributes.count("\\via_celltype"))
2133 {
2134 bool all_args_const = true;
2135 for (auto child : children) {
2136 while (child->simplify(true, false, false, 1, -1, false, true)) { }
2137 if (child->type != AST_CONSTANT)
2138 all_args_const = false;
2139 }
2140
2141 if (all_args_const) {
2142 AstNode *func_workspace = current_scope[str]->clone();
2143 newNode = func_workspace->eval_const_function(this);
2144 delete func_workspace;
2145 goto apply_newNode;
2146 }
2147
2148 if (in_param)
2149 log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum);
2150 if (require_const_eval)
2151 log_error("Function %s can only be called with constant arguments at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
2152 }
2153
2154 size_t arg_count = 0;
2155 std::map<std::string, std::string> replace_rules;
2156 vector<AstNode*> added_mod_children;
2157 dict<std::string, AstNode*> wire_cache;
2158
2159 if (current_block == NULL)
2160 {
2161 log_assert(type == AST_FCALL);
2162
2163 AstNode *wire = NULL;
2164 for (auto child : decl->children)
2165 if (child->type == AST_WIRE && child->str == str)
2166 wire = child->clone();
2167 log_assert(wire != NULL);
2168
2169 wire->str = prefix + str;
2170 wire->port_id = 0;
2171 wire->is_input = false;
2172 wire->is_output = false;
2173
2174 current_ast_mod->children.push_back(wire);
2175 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
2176
2177 AstNode *lvalue = new AstNode(AST_IDENTIFIER);
2178 lvalue->str = wire->str;
2179
2180 AstNode *always = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK,
2181 new AstNode(AST_ASSIGN_EQ, lvalue, clone())));
2182 current_ast_mod->children.push_back(always);
2183
2184 goto replace_fcall_with_id;
2185 }
2186
2187 if (decl->attributes.count("\\via_celltype"))
2188 {
2189 std::string celltype = decl->attributes.at("\\via_celltype")->asAttrConst().decode_string();
2190 std::string outport = str;
2191
2192 if (celltype.find(' ') != std::string::npos) {
2193 int pos = celltype.find(' ');
2194 outport = RTLIL::escape_id(celltype.substr(pos+1));
2195 celltype = RTLIL::escape_id(celltype.substr(0, pos));
2196 } else
2197 celltype = RTLIL::escape_id(celltype);
2198
2199 AstNode *cell = new AstNode(AST_CELL, new AstNode(AST_CELLTYPE));
2200 cell->str = prefix.substr(0, GetSize(prefix)-1);
2201 cell->children[0]->str = celltype;
2202
2203 for (auto attr : decl->attributes)
2204 if (attr.first.str().rfind("\\via_celltype_defparam_", 0) == 0)
2205 {
2206 AstNode *cell_arg = new AstNode(AST_PARASET, attr.second->clone());
2207 cell_arg->str = RTLIL::escape_id(attr.first.str().substr(strlen("\\via_celltype_defparam_")));
2208 cell->children.push_back(cell_arg);
2209 }
2210
2211 for (auto child : decl->children)
2212 if (child->type == AST_WIRE && (child->is_input || child->is_output || (type == AST_FCALL && child->str == str)))
2213 {
2214 AstNode *wire = child->clone();
2215 wire->str = prefix + wire->str;
2216 wire->port_id = 0;
2217 wire->is_input = false;
2218 wire->is_output = false;
2219 current_ast_mod->children.push_back(wire);
2220 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
2221
2222 AstNode *wire_id = new AstNode(AST_IDENTIFIER);
2223 wire_id->str = wire->str;
2224
2225 if ((child->is_input || child->is_output) && arg_count < children.size())
2226 {
2227 AstNode *arg = children[arg_count++]->clone();
2228 AstNode *assign = child->is_input ?
2229 new AstNode(AST_ASSIGN_EQ, wire_id->clone(), arg) :
2230 new AstNode(AST_ASSIGN_EQ, arg, wire_id->clone());
2231
2232 for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) {
2233 if (*it != current_block_child)
2234 continue;
2235 current_block->children.insert(it, assign);
2236 break;
2237 }
2238 }
2239
2240 AstNode *cell_arg = new AstNode(AST_ARGUMENT, wire_id);
2241 cell_arg->str = child->str == str ? outport : child->str;
2242 cell->children.push_back(cell_arg);
2243 }
2244
2245 current_ast_mod->children.push_back(cell);
2246 goto replace_fcall_with_id;
2247 }
2248
2249 for (auto child : decl->children)
2250 if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM)
2251 {
2252 AstNode *wire = nullptr;
2253
2254 if (wire_cache.count(child->str))
2255 {
2256 wire = wire_cache.at(child->str);
2257 if (wire->children.empty()) {
2258 for (auto c : child->children)
2259 wire->children.push_back(c->clone());
2260 } else if (!child->children.empty()) {
2261 while (child->simplify(true, false, false, stage, -1, false, false)) { }
2262 if (GetSize(child->children) == GetSize(wire->children)) {
2263 for (int i = 0; i < GetSize(child->children); i++)
2264 if (*child->children.at(i) != *wire->children.at(i))
2265 goto tcall_incompatible_wires;
2266 } else {
2267 tcall_incompatible_wires:
2268 log_error("Incompatible re-declaration of wire %s at %s:%d.\n", child->str.c_str(), filename.c_str(), linenum);
2269 }
2270 }
2271 }
2272 else
2273 {
2274 wire = child->clone();
2275 wire->str = prefix + wire->str;
2276 wire->port_id = 0;
2277 wire->is_input = false;
2278 wire->is_output = false;
2279 if (!child->is_output)
2280 wire->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
2281 wire_cache[child->str] = wire;
2282
2283 current_ast_mod->children.push_back(wire);
2284 added_mod_children.push_back(wire);
2285 }
2286
2287 if (child->type == AST_WIRE)
2288 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
2289
2290 replace_rules[child->str] = wire->str;
2291 current_scope[wire->str] = wire;
2292
2293 if ((child->is_input || child->is_output) && arg_count < children.size())
2294 {
2295 AstNode *arg = children[arg_count++]->clone();
2296 AstNode *wire_id = new AstNode(AST_IDENTIFIER);
2297 wire_id->str = wire->str;
2298 AstNode *assign = child->is_input ?
2299 new AstNode(AST_ASSIGN_EQ, wire_id, arg) :
2300 new AstNode(AST_ASSIGN_EQ, arg, wire_id);
2301
2302 for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) {
2303 if (*it != current_block_child)
2304 continue;
2305 current_block->children.insert(it, assign);
2306 break;
2307 }
2308 }
2309 }
2310
2311 for (auto child : added_mod_children) {
2312 child->replace_ids(prefix, replace_rules);
2313 while (child->simplify(true, false, false, 1, -1, false, false)) { }
2314 }
2315
2316 for (auto child : decl->children)
2317 if (child->type != AST_WIRE && child->type != AST_MEMORY && child->type != AST_PARAMETER && child->type != AST_LOCALPARAM)
2318 {
2319 AstNode *stmt = child->clone();
2320 stmt->replace_ids(prefix, replace_rules);
2321
2322 for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) {
2323 if (*it != current_block_child)
2324 continue;
2325 current_block->children.insert(it, stmt);
2326 break;
2327 }
2328 }
2329
2330 replace_fcall_with_id:
2331 if (type == AST_FCALL) {
2332 delete_children();
2333 type = AST_IDENTIFIER;
2334 str = prefix + str;
2335 }
2336 if (type == AST_TCALL)
2337 str = "";
2338 did_something = true;
2339 }
2340
2341 replace_fcall_later:;
2342
2343 // perform const folding when activated
2344 if (const_fold)
2345 {
2346 bool string_op;
2347 std::vector<RTLIL::State> tmp_bits;
2348 RTLIL::Const (*const_func)(const RTLIL::Const&, const RTLIL::Const&, bool, bool, int);
2349 RTLIL::Const dummy_arg;
2350
2351 switch (type)
2352 {
2353 case AST_IDENTIFIER:
2354 if (current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM)) {
2355 if (current_scope[str]->children[0]->type == AST_CONSTANT) {
2356 if (children.size() != 0 && children[0]->type == AST_RANGE && children[0]->range_valid) {
2357 std::vector<RTLIL::State> data;
2358 bool param_upto = current_scope[str]->range_valid && current_scope[str]->range_swapped;
2359 int param_offset = current_scope[str]->range_valid ? current_scope[str]->range_right : 0;
2360 int param_width = current_scope[str]->range_valid ? current_scope[str]->range_left - current_scope[str]->range_right + 1 :
2361 GetSize(current_scope[str]->children[0]->bits);
2362 int tmp_range_left = children[0]->range_left, tmp_range_right = children[0]->range_right;
2363 if (param_upto) {
2364 tmp_range_left = (param_width + 2*param_offset) - children[0]->range_right - 1;
2365 tmp_range_right = (param_width + 2*param_offset) - children[0]->range_left - 1;
2366 }
2367 for (int i = tmp_range_right; i <= tmp_range_left; i++) {
2368 int index = i - param_offset;
2369 if (0 <= index && index < param_width)
2370 data.push_back(current_scope[str]->children[0]->bits[index]);
2371 else
2372 data.push_back(RTLIL::State::Sx);
2373 }
2374 newNode = mkconst_bits(data, false);
2375 } else
2376 if (children.size() == 0)
2377 newNode = current_scope[str]->children[0]->clone();
2378 } else
2379 if (current_scope[str]->children[0]->isConst())
2380 newNode = current_scope[str]->children[0]->clone();
2381 }
2382 else if (at_zero && current_scope.count(str) > 0 && (current_scope[str]->type == AST_WIRE || current_scope[str]->type == AST_AUTOWIRE)) {
2383 newNode = mkconst_int(0, sign_hint, width_hint);
2384 }
2385 break;
2386 case AST_BIT_NOT:
2387 if (children[0]->type == AST_CONSTANT) {
2388 RTLIL::Const y = RTLIL::const_not(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint);
2389 newNode = mkconst_bits(y.bits, sign_hint);
2390 }
2391 break;
2392 case AST_TO_SIGNED:
2393 case AST_TO_UNSIGNED:
2394 if (children[0]->type == AST_CONSTANT) {
2395 RTLIL::Const y = children[0]->bitsAsConst(width_hint, sign_hint);
2396 newNode = mkconst_bits(y.bits, type == AST_TO_SIGNED);
2397 }
2398 break;
2399 if (0) { case AST_BIT_AND: const_func = RTLIL::const_and; }
2400 if (0) { case AST_BIT_OR: const_func = RTLIL::const_or; }
2401 if (0) { case AST_BIT_XOR: const_func = RTLIL::const_xor; }
2402 if (0) { case AST_BIT_XNOR: const_func = RTLIL::const_xnor; }
2403 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
2404 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
2405 children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint);
2406 newNode = mkconst_bits(y.bits, sign_hint);
2407 }
2408 break;
2409 if (0) { case AST_REDUCE_AND: const_func = RTLIL::const_reduce_and; }
2410 if (0) { case AST_REDUCE_OR: const_func = RTLIL::const_reduce_or; }
2411 if (0) { case AST_REDUCE_XOR: const_func = RTLIL::const_reduce_xor; }
2412 if (0) { case AST_REDUCE_XNOR: const_func = RTLIL::const_reduce_xnor; }
2413 if (0) { case AST_REDUCE_BOOL: const_func = RTLIL::const_reduce_bool; }
2414 if (children[0]->type == AST_CONSTANT) {
2415 RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), dummy_arg, false, false, -1);
2416 newNode = mkconst_bits(y.bits, false);
2417 }
2418 break;
2419 case AST_LOGIC_NOT:
2420 if (children[0]->type == AST_CONSTANT) {
2421 RTLIL::Const y = RTLIL::const_logic_not(RTLIL::Const(children[0]->bits), dummy_arg, children[0]->is_signed, false, -1);
2422 newNode = mkconst_bits(y.bits, false);
2423 } else
2424 if (children[0]->isConst()) {
2425 newNode = mkconst_int(children[0]->asReal(sign_hint) == 0, false, 1);
2426 }
2427 break;
2428 if (0) { case AST_LOGIC_AND: const_func = RTLIL::const_logic_and; }
2429 if (0) { case AST_LOGIC_OR: const_func = RTLIL::const_logic_or; }
2430 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
2431 RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), RTLIL::Const(children[1]->bits),
2432 children[0]->is_signed, children[1]->is_signed, -1);
2433 newNode = mkconst_bits(y.bits, false);
2434 } else
2435 if (children[0]->isConst() && children[1]->isConst()) {
2436 if (type == AST_LOGIC_AND)
2437 newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) && (children[1]->asReal(sign_hint) != 0), false, 1);
2438 else
2439 newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) || (children[1]->asReal(sign_hint) != 0), false, 1);
2440 }
2441 break;
2442 if (0) { case AST_SHIFT_LEFT: const_func = RTLIL::const_shl; }
2443 if (0) { case AST_SHIFT_RIGHT: const_func = RTLIL::const_shr; }
2444 if (0) { case AST_SHIFT_SLEFT: const_func = RTLIL::const_sshl; }
2445 if (0) { case AST_SHIFT_SRIGHT: const_func = RTLIL::const_sshr; }
2446 if (0) { case AST_POW: const_func = RTLIL::const_pow; }
2447 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
2448 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
2449 RTLIL::Const(children[1]->bits), sign_hint, type == AST_POW ? children[1]->is_signed : false, width_hint);
2450 newNode = mkconst_bits(y.bits, sign_hint);
2451 } else
2452 if (type == AST_POW && children[0]->isConst() && children[1]->isConst()) {
2453 newNode = new AstNode(AST_REALVALUE);
2454 newNode->realvalue = pow(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint));
2455 }
2456 break;
2457 if (0) { case AST_LT: const_func = RTLIL::const_lt; }
2458 if (0) { case AST_LE: const_func = RTLIL::const_le; }
2459 if (0) { case AST_EQ: const_func = RTLIL::const_eq; }
2460 if (0) { case AST_NE: const_func = RTLIL::const_ne; }
2461 if (0) { case AST_EQX: const_func = RTLIL::const_eqx; }
2462 if (0) { case AST_NEX: const_func = RTLIL::const_nex; }
2463 if (0) { case AST_GE: const_func = RTLIL::const_ge; }
2464 if (0) { case AST_GT: const_func = RTLIL::const_gt; }
2465 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
2466 int cmp_width = max(children[0]->bits.size(), children[1]->bits.size());
2467 bool cmp_signed = children[0]->is_signed && children[1]->is_signed;
2468 RTLIL::Const y = const_func(children[0]->bitsAsConst(cmp_width, cmp_signed),
2469 children[1]->bitsAsConst(cmp_width, cmp_signed), cmp_signed, cmp_signed, 1);
2470 newNode = mkconst_bits(y.bits, false);
2471 } else
2472 if (children[0]->isConst() && children[1]->isConst()) {
2473 bool cmp_signed = (children[0]->type == AST_REALVALUE || children[0]->is_signed) && (children[1]->type == AST_REALVALUE || children[1]->is_signed);
2474 switch (type) {
2475 case AST_LT: newNode = mkconst_int(children[0]->asReal(cmp_signed) < children[1]->asReal(cmp_signed), false, 1); break;
2476 case AST_LE: newNode = mkconst_int(children[0]->asReal(cmp_signed) <= children[1]->asReal(cmp_signed), false, 1); break;
2477 case AST_EQ: newNode = mkconst_int(children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break;
2478 case AST_NE: newNode = mkconst_int(children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break;
2479 case AST_EQX: newNode = mkconst_int(children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break;
2480 case AST_NEX: newNode = mkconst_int(children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break;
2481 case AST_GE: newNode = mkconst_int(children[0]->asReal(cmp_signed) >= children[1]->asReal(cmp_signed), false, 1); break;
2482 case AST_GT: newNode = mkconst_int(children[0]->asReal(cmp_signed) > children[1]->asReal(cmp_signed), false, 1); break;
2483 default: log_abort();
2484 }
2485 }
2486 break;
2487 if (0) { case AST_ADD: const_func = RTLIL::const_add; }
2488 if (0) { case AST_SUB: const_func = RTLIL::const_sub; }
2489 if (0) { case AST_MUL: const_func = RTLIL::const_mul; }
2490 if (0) { case AST_DIV: const_func = RTLIL::const_div; }
2491 if (0) { case AST_MOD: const_func = RTLIL::const_mod; }
2492 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
2493 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
2494 children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint);
2495 newNode = mkconst_bits(y.bits, sign_hint);
2496 } else
2497 if (children[0]->isConst() && children[1]->isConst()) {
2498 newNode = new AstNode(AST_REALVALUE);
2499 switch (type) {
2500 case AST_ADD: newNode->realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint); break;
2501 case AST_SUB: newNode->realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint); break;
2502 case AST_MUL: newNode->realvalue = children[0]->asReal(sign_hint) * children[1]->asReal(sign_hint); break;
2503 case AST_DIV: newNode->realvalue = children[0]->asReal(sign_hint) / children[1]->asReal(sign_hint); break;
2504 case AST_MOD: newNode->realvalue = fmod(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); break;
2505 default: log_abort();
2506 }
2507 }
2508 break;
2509 if (0) { case AST_POS: const_func = RTLIL::const_pos; }
2510 if (0) { case AST_NEG: const_func = RTLIL::const_neg; }
2511 if (children[0]->type == AST_CONSTANT) {
2512 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint);
2513 newNode = mkconst_bits(y.bits, sign_hint);
2514 } else
2515 if (children[0]->isConst()) {
2516 newNode = new AstNode(AST_REALVALUE);
2517 if (type == AST_POS)
2518 newNode->realvalue = +children[0]->asReal(sign_hint);
2519 else
2520 newNode->realvalue = -children[0]->asReal(sign_hint);
2521 }
2522 break;
2523 case AST_TERNARY:
2524 if (children[0]->isConst())
2525 {
2526 bool found_sure_true = false;
2527 bool found_maybe_true = false;
2528
2529 if (children[0]->type == AST_CONSTANT)
2530 for (auto &bit : children[0]->bits) {
2531 if (bit == RTLIL::State::S1)
2532 found_sure_true = true;
2533 if (bit > RTLIL::State::S1)
2534 found_maybe_true = true;
2535 }
2536 else
2537 found_sure_true = children[0]->asReal(sign_hint) != 0;
2538
2539 AstNode *choice = NULL, *not_choice = NULL;
2540 if (found_sure_true)
2541 choice = children[1], not_choice = children[2];
2542 else if (!found_maybe_true)
2543 choice = children[2], not_choice = children[1];
2544
2545 if (choice != NULL) {
2546 if (choice->type == AST_CONSTANT) {
2547 int other_width_hint = width_hint;
2548 bool other_sign_hint = sign_hint, other_real = false;
2549 not_choice->detectSignWidth(other_width_hint, other_sign_hint, &other_real);
2550 if (other_real) {
2551 newNode = new AstNode(AST_REALVALUE);
2552 choice->detectSignWidth(width_hint, sign_hint);
2553 newNode->realvalue = choice->asReal(sign_hint);
2554 } else {
2555 RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint);
2556 if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false)
2557 newNode = mkconst_str(y.bits);
2558 else
2559 newNode = mkconst_bits(y.bits, sign_hint);
2560 }
2561 } else
2562 if (choice->isConst()) {
2563 newNode = choice->clone();
2564 }
2565 } else if (children[1]->type == AST_CONSTANT && children[2]->type == AST_CONSTANT) {
2566 RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint);
2567 RTLIL::Const b = children[2]->bitsAsConst(width_hint, sign_hint);
2568 log_assert(a.bits.size() == b.bits.size());
2569 for (size_t i = 0; i < a.bits.size(); i++)
2570 if (a.bits[i] != b.bits[i])
2571 a.bits[i] = RTLIL::State::Sx;
2572 newNode = mkconst_bits(a.bits, sign_hint);
2573 } else if (children[1]->isConst() && children[2]->isConst()) {
2574 newNode = new AstNode(AST_REALVALUE);
2575 if (children[1]->asReal(sign_hint) == children[2]->asReal(sign_hint))
2576 newNode->realvalue = children[1]->asReal(sign_hint);
2577 else
2578 // IEEE Std 1800-2012 Sec. 11.4.11 states that the entry in Table 7-1 for
2579 // the data type in question should be returned if the ?: is ambiguous. The
2580 // value in Table 7-1 for the 'real' type is 0.0.
2581 newNode->realvalue = 0.0;
2582 }
2583 }
2584 break;
2585 case AST_CONCAT:
2586 string_op = !children.empty();
2587 for (auto it = children.begin(); it != children.end(); it++) {
2588 if ((*it)->type != AST_CONSTANT)
2589 goto not_const;
2590 if (!(*it)->is_string)
2591 string_op = false;
2592 tmp_bits.insert(tmp_bits.end(), (*it)->bits.begin(), (*it)->bits.end());
2593 }
2594 newNode = string_op ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false);
2595 break;
2596 case AST_REPLICATE:
2597 if (children.at(0)->type != AST_CONSTANT || children.at(1)->type != AST_CONSTANT)
2598 goto not_const;
2599 for (int i = 0; i < children[0]->bitsAsConst().as_int(); i++)
2600 tmp_bits.insert(tmp_bits.end(), children.at(1)->bits.begin(), children.at(1)->bits.end());
2601 newNode = children.at(1)->is_string ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false);
2602 break;
2603 default:
2604 not_const:
2605 break;
2606 }
2607 }
2608
2609 // if any of the above set 'newNode' -> use 'newNode' as template to update 'this'
2610 if (newNode) {
2611 apply_newNode:
2612 // fprintf(stderr, "----\n");
2613 // dumpAst(stderr, "- ");
2614 // newNode->dumpAst(stderr, "+ ");
2615 log_assert(newNode != NULL);
2616 newNode->filename = filename;
2617 newNode->linenum = linenum;
2618 newNode->cloneInto(this);
2619 delete newNode;
2620 did_something = true;
2621 }
2622
2623 if (!did_something)
2624 basic_prep = true;
2625
2626 recursion_counter--;
2627 return did_something;
2628 }
2629
2630 static void replace_result_wire_name_in_function(AstNode *node, std::string &from, std::string &to)
2631 {
2632 for (auto &it : node->children)
2633 replace_result_wire_name_in_function(it, from, to);
2634 if (node->str == from)
2635 node->str = to;
2636 }
2637
2638 // replace a readmem[bh] TCALL ast node with a block of memory assignments
2639 AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init)
2640 {
2641 int mem_width, mem_size, addr_bits;
2642 memory->meminfo(mem_width, mem_size, addr_bits);
2643
2644 AstNode *block = new AstNode(AST_BLOCK);
2645
2646 AstNode *meminit = nullptr;
2647 int next_meminit_cursor=0;
2648 vector<State> meminit_bits;
2649 int meminit_size=0;
2650
2651 std::ifstream f;
2652 f.open(mem_filename.c_str());
2653
2654 if (f.fail())
2655 log_error("Can not open file `%s` for %s at %s:%d.\n", mem_filename.c_str(), str.c_str(), filename.c_str(), linenum);
2656
2657 log_assert(GetSize(memory->children) == 2 && memory->children[1]->type == AST_RANGE && memory->children[1]->range_valid);
2658 int range_left = memory->children[1]->range_left, range_right = memory->children[1]->range_right;
2659 int range_min = min(range_left, range_right), range_max = max(range_left, range_right);
2660
2661 if (start_addr < 0)
2662 start_addr = range_min;
2663
2664 if (finish_addr < 0)
2665 finish_addr = range_max + 1;
2666
2667 bool in_comment = false;
2668 int increment = start_addr <= finish_addr ? +1 : -1;
2669 int cursor = start_addr;
2670
2671 while (!f.eof())
2672 {
2673 std::string line, token;
2674 std::getline(f, line);
2675
2676 for (int i = 0; i < GetSize(line); i++) {
2677 if (in_comment && line.substr(i, 2) == "*/") {
2678 line[i] = ' ';
2679 line[i+1] = ' ';
2680 in_comment = false;
2681 continue;
2682 }
2683 if (!in_comment && line.substr(i, 2) == "/*")
2684 in_comment = true;
2685 if (in_comment)
2686 line[i] = ' ';
2687 }
2688
2689 while (1)
2690 {
2691 token = next_token(line, " \t\r\n");
2692 if (token.empty() || token.substr(0, 2) == "//")
2693 break;
2694
2695 if (token[0] == '@') {
2696 token = token.substr(1);
2697 const char *nptr = token.c_str();
2698 char *endptr;
2699 cursor = strtol(nptr, &endptr, 16);
2700 if (!*nptr || *endptr)
2701 log_error("Can not parse address `%s` for %s at %s:%d.\n", nptr, str.c_str(), filename.c_str(), linenum);
2702 continue;
2703 }
2704
2705 AstNode *value = VERILOG_FRONTEND::const2ast(stringf("%d'%c", mem_width, is_readmemh ? 'h' : 'b') + token);
2706
2707 if (unconditional_init)
2708 {
2709 if (meminit == nullptr || cursor != next_meminit_cursor)
2710 {
2711 if (meminit != nullptr) {
2712 meminit->children[1] = AstNode::mkconst_bits(meminit_bits, false);
2713 meminit->children[2] = AstNode::mkconst_int(meminit_size, false);
2714 }
2715
2716 meminit = new AstNode(AST_MEMINIT);
2717 meminit->children.push_back(AstNode::mkconst_int(cursor, false));
2718 meminit->children.push_back(nullptr);
2719 meminit->children.push_back(nullptr);
2720 meminit->str = memory->str;
2721 meminit->id2ast = memory;
2722 meminit_bits.clear();
2723 meminit_size = 0;
2724
2725 current_ast_mod->children.push_back(meminit);
2726 next_meminit_cursor = cursor;
2727 }
2728
2729 meminit_size++;
2730 next_meminit_cursor++;
2731 meminit_bits.insert(meminit_bits.end(), value->bits.begin(), value->bits.end());
2732 delete value;
2733 }
2734 else
2735 {
2736 block->children.push_back(new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER, new AstNode(AST_RANGE, AstNode::mkconst_int(cursor, false))), value));
2737 block->children.back()->children[0]->str = memory->str;
2738 block->children.back()->children[0]->id2ast = memory;
2739 }
2740
2741 cursor += increment;
2742 if ((cursor == finish_addr+increment) || (increment > 0 && cursor > range_max) || (increment < 0 && cursor < range_min))
2743 break;
2744 }
2745
2746 if ((cursor == finish_addr+increment) || (increment > 0 && cursor > range_max) || (increment < 0 && cursor < range_min))
2747 break;
2748 }
2749
2750 if (meminit != nullptr) {
2751 meminit->children[1] = AstNode::mkconst_bits(meminit_bits, false);
2752 meminit->children[2] = AstNode::mkconst_int(meminit_size, false);
2753 }
2754
2755 return block;
2756 }
2757
2758 // annotate the names of all wires and other named objects in a generate block
2759 void AstNode::expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map)
2760 {
2761 if (!index_var.empty() && type == AST_IDENTIFIER && str == index_var) {
2762 current_scope[index_var]->children[0]->cloneInto(this);
2763 return;
2764 }
2765
2766 if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL) && name_map.count(str) > 0)
2767 str = name_map[str];
2768
2769 std::map<std::string, std::string> backup_name_map;
2770
2771 for (size_t i = 0; i < children.size(); i++) {
2772 AstNode *child = children[i];
2773 if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM ||
2774 child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL) {
2775 if (backup_name_map.size() == 0)
2776 backup_name_map = name_map;
2777 std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix;
2778 size_t pos = child->str.rfind('.');
2779 if (pos == std::string::npos)
2780 pos = child->str[0] == '\\' && prefix[0] == '\\' ? 1 : 0;
2781 else
2782 pos = pos + 1;
2783 new_name = child->str.substr(0, pos) + new_name + child->str.substr(pos);
2784 if (new_name[0] != '$' && new_name[0] != '\\')
2785 new_name = prefix[0] + new_name;
2786 name_map[child->str] = new_name;
2787 if (child->type == AST_FUNCTION)
2788 replace_result_wire_name_in_function(child, child->str, new_name);
2789 else
2790 child->str = new_name;
2791 current_scope[new_name] = child;
2792 }
2793 }
2794
2795 for (size_t i = 0; i < children.size(); i++) {
2796 AstNode *child = children[i];
2797 if (child->type != AST_FUNCTION && child->type != AST_TASK && child->type != AST_PREFIX)
2798 child->expand_genblock(index_var, prefix, name_map);
2799 }
2800
2801 if (backup_name_map.size() > 0)
2802 name_map.swap(backup_name_map);
2803 }
2804
2805 // rename stuff (used when tasks of functions are instantiated)
2806 void AstNode::replace_ids(const std::string &prefix, const std::map<std::string, std::string> &rules)
2807 {
2808 if (type == AST_BLOCK)
2809 {
2810 std::map<std::string, std::string> new_rules = rules;
2811 std::string new_prefix = prefix + str;
2812
2813 for (auto child : children)
2814 if (child->type == AST_WIRE) {
2815 new_rules[child->str] = new_prefix + child->str;
2816 child->str = new_prefix + child->str;
2817 }
2818
2819 for (auto child : children)
2820 if (child->type != AST_WIRE)
2821 child->replace_ids(new_prefix, new_rules);
2822 }
2823 else
2824 {
2825 if (type == AST_IDENTIFIER && rules.count(str) > 0)
2826 str = rules.at(str);
2827 for (auto child : children)
2828 child->replace_ids(prefix, rules);
2829 }
2830 }
2831
2832 // helper function for mem2reg_as_needed_pass1
2833 static void mark_memories_assign_lhs_complex(dict<AstNode*, pool<std::string>> &mem2reg_places,
2834 dict<AstNode*, uint32_t> &mem2reg_candidates, AstNode *that)
2835 {
2836 for (auto &child : that->children)
2837 mark_memories_assign_lhs_complex(mem2reg_places, mem2reg_candidates, child);
2838
2839 if (that->type == AST_IDENTIFIER && that->id2ast && that->id2ast->type == AST_MEMORY) {
2840 AstNode *mem = that->id2ast;
2841 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_CMPLX_LHS))
2842 mem2reg_places[mem].insert(stringf("%s:%d", that->filename.c_str(), that->linenum));
2843 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CMPLX_LHS;
2844 }
2845 }
2846
2847 // find memories that should be replaced by registers
2848 void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg_places,
2849 dict<AstNode*, uint32_t> &mem2reg_candidates, dict<AstNode*, uint32_t> &proc_flags, uint32_t &flags)
2850 {
2851 uint32_t children_flags = 0;
2852 int ignore_children_counter = 0;
2853
2854 if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ)
2855 {
2856 // mark all memories that are used in a complex expression on the left side of an assignment
2857 for (auto &lhs_child : children[0]->children)
2858 mark_memories_assign_lhs_complex(mem2reg_places, mem2reg_candidates, lhs_child);
2859
2860 if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY)
2861 {
2862 AstNode *mem = children[0]->id2ast;
2863
2864 // activate mem2reg if this is assigned in an async proc
2865 if (flags & AstNode::MEM2REG_FL_ASYNC) {
2866 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ASYNC))
2867 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
2868 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ASYNC;
2869 }
2870
2871 // remember if this is assigned blocking (=)
2872 if (type == AST_ASSIGN_EQ) {
2873 if (!(proc_flags[mem] & AstNode::MEM2REG_FL_EQ1))
2874 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
2875 proc_flags[mem] |= AstNode::MEM2REG_FL_EQ1;
2876 }
2877
2878 // remember where this is
2879 if (flags & MEM2REG_FL_INIT) {
2880 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_INIT))
2881 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
2882 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_INIT;
2883 } else {
2884 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ELSE))
2885 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
2886 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ELSE;
2887 }
2888 }
2889
2890 ignore_children_counter = 1;
2891 }
2892
2893 if (type == AST_IDENTIFIER && id2ast && id2ast->type == AST_MEMORY)
2894 {
2895 AstNode *mem = id2ast;
2896
2897 // flag if used after blocking assignment (in same proc)
2898 if ((proc_flags[mem] & AstNode::MEM2REG_FL_EQ1) && !(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_EQ2)) {
2899 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
2900 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_EQ2;
2901 }
2902 }
2903
2904 // also activate if requested, either by using mem2reg attribute or by declaring array as 'wire' instead of 'reg'
2905 if (type == AST_MEMORY && (get_bool_attribute("\\mem2reg") || (flags & AstNode::MEM2REG_FL_ALL) || !is_reg))
2906 mem2reg_candidates[this] |= AstNode::MEM2REG_FL_FORCED;
2907
2908 if (type == AST_MODULE && get_bool_attribute("\\mem2reg"))
2909 children_flags |= AstNode::MEM2REG_FL_ALL;
2910
2911 dict<AstNode*, uint32_t> *proc_flags_p = NULL;
2912
2913 if (type == AST_ALWAYS) {
2914 int count_edge_events = 0;
2915 for (auto child : children)
2916 if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE)
2917 count_edge_events++;
2918 if (count_edge_events != 1)
2919 children_flags |= AstNode::MEM2REG_FL_ASYNC;
2920 proc_flags_p = new dict<AstNode*, uint32_t>;
2921 }
2922
2923 if (type == AST_INITIAL) {
2924 children_flags |= AstNode::MEM2REG_FL_INIT;
2925 proc_flags_p = new dict<AstNode*, uint32_t>;
2926 }
2927
2928 uint32_t backup_flags = flags;
2929 flags |= children_flags;
2930 log_assert((flags & ~0x000000ff) == 0);
2931
2932 for (auto child : children)
2933 if (ignore_children_counter > 0)
2934 ignore_children_counter--;
2935 else if (proc_flags_p)
2936 child->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, *proc_flags_p, flags);
2937 else
2938 child->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, proc_flags, flags);
2939
2940 flags &= ~children_flags | backup_flags;
2941
2942 if (proc_flags_p) {
2943 #ifndef NDEBUG
2944 for (auto it : *proc_flags_p)
2945 log_assert((it.second & ~0xff000000) == 0);
2946 #endif
2947 delete proc_flags_p;
2948 }
2949 }
2950
2951 bool AstNode::mem2reg_check(pool<AstNode*> &mem2reg_set)
2952 {
2953 if (type != AST_IDENTIFIER || !id2ast || !mem2reg_set.count(id2ast))
2954 return false;
2955
2956 if (children.empty() || children[0]->type != AST_RANGE || GetSize(children[0]->children) != 1)
2957 log_error("Invalid array access at %s:%d.\n", filename.c_str(), linenum);
2958
2959 return true;
2960 }
2961
2962 void AstNode::mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes)
2963 {
2964 log_assert(mem2reg_set.count(this) == 0);
2965
2966 if (mem2reg_set.count(id2ast))
2967 id2ast = nullptr;
2968
2969 for (size_t i = 0; i < children.size(); i++) {
2970 if (mem2reg_set.count(children[i]) > 0) {
2971 delnodes.push_back(children[i]);
2972 children.erase(children.begin() + (i--));
2973 } else {
2974 children[i]->mem2reg_remove(mem2reg_set, delnodes);
2975 }
2976 }
2977 }
2978
2979 // actually replace memories with registers
2980 bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block, AstNode *&async_block)
2981 {
2982 bool did_something = false;
2983
2984 if (type == AST_BLOCK)
2985 block = this;
2986
2987 if (type == AST_FUNCTION || type == AST_TASK)
2988 return false;
2989
2990 if (type == AST_ASSIGN && block == NULL && children[0]->mem2reg_check(mem2reg_set))
2991 {
2992 if (async_block == NULL) {
2993 async_block = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
2994 mod->children.push_back(async_block);
2995 }
2996
2997 AstNode *newNode = clone();
2998 newNode->type = AST_ASSIGN_EQ;
2999 async_block->children[0]->children.push_back(newNode);
3000
3001 newNode = new AstNode(AST_NONE);
3002 newNode->cloneInto(this);
3003 delete newNode;
3004
3005 did_something = true;
3006 }
3007
3008 if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && children[0]->mem2reg_check(mem2reg_set) &&
3009 children[0]->children[0]->children[0]->type != AST_CONSTANT)
3010 {
3011 std::stringstream sstr;
3012 sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++);
3013 std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
3014
3015 int mem_width, mem_size, addr_bits;
3016 bool mem_signed = children[0]->id2ast->is_signed;
3017 children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
3018
3019 AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
3020 wire_addr->str = id_addr;
3021 wire_addr->is_reg = true;
3022 wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
3023 mod->children.push_back(wire_addr);
3024 while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
3025
3026 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
3027 wire_data->str = id_data;
3028 wire_data->is_reg = true;
3029 wire_data->is_signed = mem_signed;
3030 wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
3031 mod->children.push_back(wire_data);
3032 while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
3033
3034 log_assert(block != NULL);
3035 size_t assign_idx = 0;
3036 while (assign_idx < block->children.size() && block->children[assign_idx] != this)
3037 assign_idx++;
3038 log_assert(assign_idx < block->children.size());
3039
3040 AstNode *assign_addr = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());
3041 assign_addr->children[0]->str = id_addr;
3042 block->children.insert(block->children.begin()+assign_idx+1, assign_addr);
3043
3044 AstNode *case_node = new AstNode(AST_CASE, new AstNode(AST_IDENTIFIER));
3045 case_node->children[0]->str = id_addr;
3046 for (int i = 0; i < mem_size; i++) {
3047 if (children[0]->children[0]->children[0]->type == AST_CONSTANT && int(children[0]->children[0]->children[0]->integer) != i)
3048 continue;
3049 AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK));
3050 AstNode *assign_reg = new AstNode(type, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER));
3051 if (children[0]->children.size() == 2)
3052 assign_reg->children[0]->children.push_back(children[0]->children[1]->clone());
3053 assign_reg->children[0]->str = stringf("%s[%d]", children[0]->str.c_str(), i);
3054 assign_reg->children[1]->str = id_data;
3055 cond_node->children[1]->children.push_back(assign_reg);
3056 case_node->children.push_back(cond_node);
3057 }
3058 block->children.insert(block->children.begin()+assign_idx+2, case_node);
3059
3060 children[0]->delete_children();
3061 children[0]->range_valid = false;
3062 children[0]->id2ast = NULL;
3063 children[0]->str = id_data;
3064 type = AST_ASSIGN_EQ;
3065
3066 did_something = true;
3067 }
3068
3069 if (mem2reg_check(mem2reg_set))
3070 {
3071 AstNode *bit_part_sel = NULL;
3072 if (children.size() == 2)
3073 bit_part_sel = children[1]->clone();
3074
3075 if (children[0]->children[0]->type == AST_CONSTANT)
3076 {
3077 int id = children[0]->children[0]->integer;
3078 str = stringf("%s[%d]", str.c_str(), id);
3079
3080 delete_children();
3081 range_valid = false;
3082 id2ast = NULL;
3083 }
3084 else
3085 {
3086 std::stringstream sstr;
3087 sstr << "$mem2reg_rd$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++);
3088 std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
3089
3090 int mem_width, mem_size, addr_bits;
3091 bool mem_signed = id2ast->is_signed;
3092 id2ast->meminfo(mem_width, mem_size, addr_bits);
3093
3094 AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
3095 wire_addr->str = id_addr;
3096 wire_addr->is_reg = true;
3097 if (block)
3098 wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
3099 mod->children.push_back(wire_addr);
3100 while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
3101
3102 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
3103 wire_data->str = id_data;
3104 wire_data->is_reg = true;
3105 wire_data->is_signed = mem_signed;
3106 if (block)
3107 wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
3108 mod->children.push_back(wire_data);
3109 while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
3110
3111 AstNode *assign_addr = new AstNode(block ? AST_ASSIGN_EQ : AST_ASSIGN, new AstNode(AST_IDENTIFIER), children[0]->children[0]->clone());
3112 assign_addr->children[0]->str = id_addr;
3113
3114 AstNode *case_node = new AstNode(AST_CASE, new AstNode(AST_IDENTIFIER));
3115 case_node->children[0]->str = id_addr;
3116
3117 for (int i = 0; i < mem_size; i++) {
3118 if (children[0]->children[0]->type == AST_CONSTANT && int(children[0]->children[0]->integer) != i)
3119 continue;
3120 AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK));
3121 AstNode *assign_reg = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER));
3122 assign_reg->children[0]->str = id_data;
3123 assign_reg->children[1]->str = stringf("%s[%d]", str.c_str(), i);
3124 cond_node->children[1]->children.push_back(assign_reg);
3125 case_node->children.push_back(cond_node);
3126 }
3127
3128 std::vector<RTLIL::State> x_bits;
3129 for (int i = 0; i < mem_width; i++)
3130 x_bits.push_back(RTLIL::State::Sx);
3131
3132 AstNode *cond_node = new AstNode(AST_COND, new AstNode(AST_DEFAULT), new AstNode(AST_BLOCK));
3133 AstNode *assign_reg = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), AstNode::mkconst_bits(x_bits, false));
3134 assign_reg->children[0]->str = id_data;
3135 cond_node->children[1]->children.push_back(assign_reg);
3136 case_node->children.push_back(cond_node);
3137
3138 if (block)
3139 {
3140 size_t assign_idx = 0;
3141 while (assign_idx < block->children.size() && !block->children[assign_idx]->contains(this))
3142 assign_idx++;
3143 log_assert(assign_idx < block->children.size());
3144 block->children.insert(block->children.begin()+assign_idx, case_node);
3145 block->children.insert(block->children.begin()+assign_idx, assign_addr);
3146 }
3147 else
3148 {
3149 AstNode *proc = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
3150 proc->children[0]->children.push_back(case_node);
3151 mod->children.push_back(proc);
3152 mod->children.push_back(assign_addr);
3153 }
3154
3155 delete_children();
3156 range_valid = false;
3157 id2ast = NULL;
3158 str = id_data;
3159 }
3160
3161 if (bit_part_sel)
3162 children.push_back(bit_part_sel);
3163
3164 did_something = true;
3165 }
3166
3167 log_assert(id2ast == NULL || mem2reg_set.count(id2ast) == 0);
3168
3169 auto children_list = children;
3170 for (size_t i = 0; i < children_list.size(); i++)
3171 if (children_list[i]->mem2reg_as_needed_pass2(mem2reg_set, mod, block, async_block))
3172 did_something = true;
3173
3174 return did_something;
3175 }
3176
3177 // calculate memory dimensions
3178 void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits)
3179 {
3180 log_assert(type == AST_MEMORY);
3181
3182 mem_width = children[0]->range_left - children[0]->range_right + 1;
3183 mem_size = children[1]->range_left - children[1]->range_right;
3184
3185 if (mem_size < 0)
3186 mem_size *= -1;
3187 mem_size += min(children[1]->range_left, children[1]->range_right) + 1;
3188
3189 addr_bits = 1;
3190 while ((1 << addr_bits) < mem_size)
3191 addr_bits++;
3192 }
3193
3194 bool AstNode::has_const_only_constructs(bool &recommend_const_eval)
3195 {
3196 if (type == AST_FOR)
3197 recommend_const_eval = true;
3198 if (type == AST_WHILE || type == AST_REPEAT)
3199 return true;
3200 if (type == AST_FCALL && current_scope.count(str))
3201 if (current_scope[str]->has_const_only_constructs(recommend_const_eval))
3202 return true;
3203 for (auto child : children)
3204 if (child->AstNode::has_const_only_constructs(recommend_const_eval))
3205 return true;
3206 return false;
3207 }
3208
3209 // helper function for AstNode::eval_const_function()
3210 void AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &variables, AstNode *fcall)
3211 {
3212 if (type == AST_IDENTIFIER && variables.count(str)) {
3213 int offset = variables.at(str).offset, width = variables.at(str).val.bits.size();
3214 if (!children.empty()) {
3215 if (children.size() != 1 || children.at(0)->type != AST_RANGE)
3216 log_error("Memory access in constant function is not supported in %s:%d (called from %s:%d).\n",
3217 filename.c_str(), linenum, fcall->filename.c_str(), fcall->linenum);
3218 children.at(0)->replace_variables(variables, fcall);
3219 while (simplify(true, false, false, 1, -1, false, true)) { }
3220 if (!children.at(0)->range_valid)
3221 log_error("Non-constant range in %s:%d (called from %s:%d).\n",
3222 filename.c_str(), linenum, fcall->filename.c_str(), fcall->linenum);
3223 offset = min(children.at(0)->range_left, children.at(0)->range_right);
3224 width = min(std::abs(children.at(0)->range_left - children.at(0)->range_right) + 1, width);
3225 }
3226 offset -= variables.at(str).offset;
3227 std::vector<RTLIL::State> &var_bits = variables.at(str).val.bits;
3228 std::vector<RTLIL::State> new_bits(var_bits.begin() + offset, var_bits.begin() + offset + width);
3229 AstNode *newNode = mkconst_bits(new_bits, variables.at(str).is_signed);
3230 newNode->cloneInto(this);
3231 delete newNode;
3232 return;
3233 }
3234
3235 for (auto &child : children)
3236 child->replace_variables(variables, fcall);
3237 }
3238
3239 // evaluate functions with all-const arguments
3240 AstNode *AstNode::eval_const_function(AstNode *fcall)
3241 {
3242 std::map<std::string, AstNode*> backup_scope;
3243 std::map<std::string, AstNode::varinfo_t> variables;
3244 bool delete_temp_block = false;
3245 AstNode *block = NULL;
3246
3247 size_t argidx = 0;
3248 for (auto child : children)
3249 {
3250 if (child->type == AST_BLOCK)
3251 {
3252 log_assert(block == NULL);
3253 block = child;
3254 continue;
3255 }
3256
3257 if (child->type == AST_WIRE)
3258 {
3259 while (child->simplify(true, false, false, 1, -1, false, true)) { }
3260 if (!child->range_valid)
3261 log_error("Can't determine size of variable %s in %s:%d (called from %s:%d).\n",
3262 child->str.c_str(), child->filename.c_str(), child->linenum, fcall->filename.c_str(), fcall->linenum);
3263 variables[child->str].val = RTLIL::Const(RTLIL::State::Sx, abs(child->range_left - child->range_right)+1);
3264 variables[child->str].offset = min(child->range_left, child->range_right);
3265 variables[child->str].is_signed = child->is_signed;
3266 if (child->is_input && argidx < fcall->children.size())
3267 variables[child->str].val = fcall->children.at(argidx++)->bitsAsConst(variables[child->str].val.bits.size());
3268 backup_scope[child->str] = current_scope[child->str];
3269 current_scope[child->str] = child;
3270 continue;
3271 }
3272
3273 log_assert(block == NULL);
3274 delete_temp_block = true;
3275 block = new AstNode(AST_BLOCK);
3276 block->children.push_back(child->clone());
3277 }
3278
3279 log_assert(block != NULL);
3280 log_assert(variables.count(str) != 0);
3281
3282 while (!block->children.empty())
3283 {
3284 AstNode *stmt = block->children.front();
3285
3286 #if 0
3287 log("-----------------------------------\n");
3288 for (auto &it : variables)
3289 log("%20s %40s\n", it.first.c_str(), log_signal(it.second.val));
3290 stmt->dumpAst(NULL, "stmt> ");
3291 #endif
3292
3293 if (stmt->type == AST_ASSIGN_EQ)
3294 {
3295 if (stmt->children.at(0)->type == AST_IDENTIFIER && stmt->children.at(0)->children.size() != 0 &&
3296 stmt->children.at(0)->children.at(0)->type == AST_RANGE)
3297 stmt->children.at(0)->children.at(0)->replace_variables(variables, fcall);
3298 stmt->children.at(1)->replace_variables(variables, fcall);
3299 while (stmt->simplify(true, false, false, 1, -1, false, true)) { }
3300
3301 if (stmt->type != AST_ASSIGN_EQ)
3302 continue;
3303
3304 if (stmt->children.at(1)->type != AST_CONSTANT)
3305 log_error("Non-constant expression in constant function at %s:%d (called from %s:%d). X\n",
3306 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
3307
3308 if (stmt->children.at(0)->type != AST_IDENTIFIER)
3309 log_error("Unsupported composite left hand side in constant function at %s:%d (called from %s:%d).\n",
3310 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
3311
3312 if (!variables.count(stmt->children.at(0)->str))
3313 log_error("Assignment to non-local variable in constant function at %s:%d (called from %s:%d).\n",
3314 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
3315
3316 if (stmt->children.at(0)->children.empty()) {
3317 variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size());
3318 } else {
3319 AstNode *range = stmt->children.at(0)->children.at(0);
3320 if (!range->range_valid)
3321 log_error("Non-constant range in %s:%d (called from %s:%d).\n",
3322 range->filename.c_str(), range->linenum, fcall->filename.c_str(), fcall->linenum);
3323 int offset = min(range->range_left, range->range_right);
3324 int width = std::abs(range->range_left - range->range_right) + 1;
3325 varinfo_t &v = variables[stmt->children.at(0)->str];
3326 RTLIL::Const r = stmt->children.at(1)->bitsAsConst(v.val.bits.size());
3327 for (int i = 0; i < width; i++)
3328 v.val.bits.at(i+offset-v.offset) = r.bits.at(i);
3329 }
3330
3331 delete block->children.front();
3332 block->children.erase(block->children.begin());
3333 continue;
3334 }
3335
3336 if (stmt->type == AST_FOR)
3337 {
3338 block->children.insert(block->children.begin(), stmt->children.at(0));
3339 stmt->children.at(3)->children.push_back(stmt->children.at(2));
3340 stmt->children.erase(stmt->children.begin() + 2);
3341 stmt->children.erase(stmt->children.begin());
3342 stmt->type = AST_WHILE;
3343 continue;
3344 }
3345
3346 if (stmt->type == AST_WHILE)
3347 {
3348 AstNode *cond = stmt->children.at(0)->clone();
3349 cond->replace_variables(variables, fcall);
3350 while (cond->simplify(true, false, false, 1, -1, false, true)) { }
3351
3352 if (cond->type != AST_CONSTANT)
3353 log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n",
3354 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
3355
3356 if (cond->asBool()) {
3357 block->children.insert(block->children.begin(), stmt->children.at(1)->clone());
3358 } else {
3359 delete block->children.front();
3360 block->children.erase(block->children.begin());
3361 }
3362
3363 delete cond;
3364 continue;
3365 }
3366
3367 if (stmt->type == AST_REPEAT)
3368 {
3369 AstNode *num = stmt->children.at(0)->clone();
3370 num->replace_variables(variables, fcall);
3371 while (num->simplify(true, false, false, 1, -1, false, true)) { }
3372
3373 if (num->type != AST_CONSTANT)
3374 log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n",
3375 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
3376
3377 block->children.erase(block->children.begin());
3378 for (int i = 0; i < num->bitsAsConst().as_int(); i++)
3379 block->children.insert(block->children.begin(), stmt->children.at(1)->clone());
3380
3381 delete stmt;
3382 delete num;
3383 continue;
3384 }
3385
3386 if (stmt->type == AST_CASE)
3387 {
3388 AstNode *expr = stmt->children.at(0)->clone();
3389 expr->replace_variables(variables, fcall);
3390 while (expr->simplify(true, false, false, 1, -1, false, true)) { }
3391
3392 AstNode *sel_case = NULL;
3393 for (size_t i = 1; i < stmt->children.size(); i++)
3394 {
3395 bool found_match = false;
3396 log_assert(stmt->children.at(i)->type == AST_COND || stmt->children.at(i)->type == AST_CONDX || stmt->children.at(i)->type == AST_CONDZ);
3397
3398 if (stmt->children.at(i)->children.front()->type == AST_DEFAULT) {
3399 sel_case = stmt->children.at(i)->children.back();
3400 continue;
3401 }
3402
3403 for (size_t j = 0; j+1 < stmt->children.at(i)->children.size() && !found_match; j++)
3404 {
3405 AstNode *cond = stmt->children.at(i)->children.at(j)->clone();
3406 cond->replace_variables(variables, fcall);
3407
3408 cond = new AstNode(AST_EQ, expr->clone(), cond);
3409 while (cond->simplify(true, false, false, 1, -1, false, true)) { }
3410
3411 if (cond->type != AST_CONSTANT)
3412 log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n",
3413 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
3414
3415 found_match = cond->asBool();
3416 delete cond;
3417 }
3418
3419 if (found_match) {
3420 sel_case = stmt->children.at(i)->children.back();
3421 break;
3422 }
3423 }
3424
3425 block->children.erase(block->children.begin());
3426 if (sel_case)
3427 block->children.insert(block->children.begin(), sel_case->clone());
3428 delete stmt;
3429 delete expr;
3430 continue;
3431 }
3432
3433 if (stmt->type == AST_BLOCK)
3434 {
3435 block->children.erase(block->children.begin());
3436 block->children.insert(block->children.begin(), stmt->children.begin(), stmt->children.end());
3437 stmt->children.clear();
3438 delete stmt;
3439 continue;
3440 }
3441
3442 log_error("Unsupported language construct in constant function at %s:%d (called from %s:%d).\n",
3443 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
3444 log_abort();
3445 }
3446
3447 if (delete_temp_block)
3448 delete block;
3449
3450 for (auto &it : backup_scope)
3451 if (it.second == NULL)
3452 current_scope.erase(it.first);
3453 else
3454 current_scope[it.first] = it.second;
3455
3456 return AstNode::mkconst_bits(variables.at(str).val.bits, variables.at(str).is_signed);
3457 }
3458
3459 YOSYS_NAMESPACE_END
3460