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