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