2572fa4a93d00e14e11be1d958fdfa6b86778275
[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 "ast.h"
32
33 #include <sstream>
34 #include <stdarg.h>
35 #include <math.h>
36
37 YOSYS_NAMESPACE_BEGIN
38
39 using namespace AST;
40 using namespace AST_INTERNAL;
41
42 // convert the AST into a simpler AST that has all parameters subsitited by their
43 // values, unrolled for-loops, expanded generate blocks, etc. when this function
44 // is done with an AST it can be converted into RTLIL using genRTLIL().
45 //
46 // this function also does all name resolving and sets the id2ast member of all
47 // nodes that link to a different node using names and lexical scoping.
48 bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param)
49 {
50 AstNode *newNode = NULL;
51 bool did_something = false;
52
53 #if 0
54 log("-------------\n");
55 log("const_fold=%d, at_zero=%d, in_lvalue=%d, stage=%d, width_hint=%d, sign_hint=%d, in_param=%d\n",
56 int(const_fold), int(at_zero), int(in_lvalue), int(stage), int(width_hint), int(sign_hint), int(in_param));
57 dumpAst(NULL, "> ");
58 #endif
59
60 if (stage == 0)
61 {
62 log_assert(type == AST_MODULE);
63
64 while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint, in_param)) { }
65
66 if (!flag_nomem2reg && !get_bool_attribute("\\nomem2reg"))
67 {
68 std::map<AstNode*, std::set<std::string>> mem2reg_places;
69 std::map<AstNode*, uint32_t> mem2reg_candidates, dummy_proc_flags;
70 uint32_t flags = flag_mem2reg ? AstNode::MEM2REG_FL_ALL : 0;
71 mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, dummy_proc_flags, flags);
72
73 std::set<AstNode*> mem2reg_set;
74 for (auto &it : mem2reg_candidates)
75 {
76 AstNode *mem = it.first;
77 uint32_t memflags = it.second;
78 log_assert((memflags & ~0x00ffff00) == 0);
79
80 if (mem->get_bool_attribute("\\nomem2reg"))
81 continue;
82
83 if (memflags & AstNode::MEM2REG_FL_FORCED)
84 goto silent_activate;
85
86 if (memflags & AstNode::MEM2REG_FL_EQ2)
87 goto verbose_activate;
88
89 if (memflags & AstNode::MEM2REG_FL_SET_ASYNC)
90 goto verbose_activate;
91
92 if ((memflags & AstNode::MEM2REG_FL_SET_INIT) && (memflags & AstNode::MEM2REG_FL_SET_ELSE))
93 goto verbose_activate;
94
95 if (memflags & AstNode::MEM2REG_FL_CMPLX_LHS)
96 goto verbose_activate;
97
98 // log("Note: Not replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
99 continue;
100
101 verbose_activate:
102 if (mem2reg_set.count(mem) == 0) {
103 log("Warning: Replacing memory %s with list of registers.", mem->str.c_str());
104 bool first_element = true;
105 for (auto &place : mem2reg_places[it.first]) {
106 log("%s%s", first_element ? " See " : ", ", place.c_str());
107 first_element = false;
108 }
109 log("\n");
110 }
111
112 silent_activate:
113 // log("Note: Replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
114 mem2reg_set.insert(mem);
115 }
116
117 for (auto node : mem2reg_set)
118 {
119 int mem_width, mem_size, addr_bits;
120 node->meminfo(mem_width, mem_size, addr_bits);
121
122 for (int i = 0; i < mem_size; i++) {
123 AstNode *reg = new AstNode(AST_WIRE, new AstNode(AST_RANGE,
124 mkconst_int(mem_width-1, true), mkconst_int(0, true)));
125 reg->str = stringf("%s[%d]", node->str.c_str(), i);
126 reg->is_reg = true;
127 reg->is_signed = node->is_signed;
128 children.push_back(reg);
129 while (reg->simplify(true, false, false, 1, -1, false, false)) { }
130 }
131 }
132
133 mem2reg_as_needed_pass2(mem2reg_set, this, NULL);
134
135 for (size_t i = 0; i < children.size(); i++) {
136 if (mem2reg_set.count(children[i]) > 0) {
137 delete children[i];
138 children.erase(children.begin() + (i--));
139 }
140 }
141 }
142
143 while (simplify(const_fold, at_zero, in_lvalue, 2, width_hint, sign_hint, in_param)) { }
144 return false;
145 }
146
147 current_filename = filename;
148 set_line_num(linenum);
149
150 // we do not look inside a task or function
151 // (but as soon as a task of function is instanciated we process the generated AST as usual)
152 if (type == AST_FUNCTION || type == AST_TASK)
153 return false;
154
155 // deactivate all calls to non-synthesis system taks
156 if ((type == AST_FCALL || type == AST_TCALL) && (str == "$display" || str == "$stop" || str == "$finish")) {
157 delete_children();
158 str = std::string();
159 }
160
161 // activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
162 if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX)
163 const_fold = true;
164 if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM))
165 const_fold = true;
166
167 // in certain cases a function must be evaluated constant. this is what in_param controls.
168 if (type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_PREFIX)
169 in_param = true;
170
171 std::map<std::string, AstNode*> backup_scope;
172
173 // create name resolution entries for all objects with names
174 // also merge multiple declarations for the same wire (e.g. "output foobar; reg foobar;")
175 if (type == AST_MODULE) {
176 current_scope.clear();
177 std::map<std::string, AstNode*> this_wire_scope;
178 for (size_t i = 0; i < children.size(); i++) {
179 AstNode *node = children[i];
180 if (node->type == AST_WIRE) {
181 if (this_wire_scope.count(node->str) > 0) {
182 AstNode *first_node = this_wire_scope[node->str];
183 if (!node->is_input && !node->is_output && node->is_reg && node->children.size() == 0)
184 goto wires_are_compatible;
185 if (first_node->children.size() != node->children.size())
186 goto wires_are_incompatible;
187 for (size_t j = 0; j < node->children.size(); j++) {
188 AstNode *n1 = first_node->children[j], *n2 = node->children[j];
189 if (n1->type == AST_RANGE && n2->type == AST_RANGE && n1->range_valid && n2->range_valid) {
190 if (n1->range_left != n2->range_left)
191 goto wires_are_incompatible;
192 if (n1->range_right != n2->range_right)
193 goto wires_are_incompatible;
194 } else if (*n1 != *n2)
195 goto wires_are_incompatible;
196 }
197 if (first_node->range_left != node->range_left)
198 goto wires_are_incompatible;
199 if (first_node->range_right != node->range_right)
200 goto wires_are_incompatible;
201 if (first_node->port_id == 0 && (node->is_input || node->is_output))
202 goto wires_are_incompatible;
203 wires_are_compatible:
204 if (node->is_input)
205 first_node->is_input = true;
206 if (node->is_output)
207 first_node->is_output = true;
208 if (node->is_reg)
209 first_node->is_reg = true;
210 if (node->is_signed)
211 first_node->is_signed = true;
212 for (auto &it : node->attributes) {
213 if (first_node->attributes.count(it.first) > 0)
214 delete first_node->attributes[it.first];
215 first_node->attributes[it.first] = it.second->clone();
216 }
217 children.erase(children.begin()+(i--));
218 did_something = true;
219 delete node;
220 continue;
221 wires_are_incompatible:
222 if (stage > 1)
223 log_error("Incompatible re-declaration of wire %s at %s:%d.\n", node->str.c_str(), filename.c_str(), linenum);
224 continue;
225 }
226 this_wire_scope[node->str] = node;
227 }
228 if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
229 node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_CELL) {
230 backup_scope[node->str] = current_scope[node->str];
231 current_scope[node->str] = node;
232 }
233 }
234 for (size_t i = 0; i < children.size(); i++) {
235 AstNode *node = children[i];
236 if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE)
237 while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM))
238 did_something = true;
239 }
240 }
241
242 auto backup_current_block = current_block;
243 auto backup_current_block_child = current_block_child;
244 auto backup_current_top_block = current_top_block;
245
246 int backup_width_hint = width_hint;
247 bool backup_sign_hint = sign_hint;
248
249 bool detect_width_simple = false;
250 bool child_0_is_self_determined = false;
251 bool child_1_is_self_determined = false;
252 bool child_2_is_self_determined = false;
253 bool children_are_self_determined = false;
254 bool reset_width_after_children = false;
255
256 switch (type)
257 {
258 case AST_ASSIGN_EQ:
259 case AST_ASSIGN_LE:
260 case AST_ASSIGN:
261 while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, in_param) == true)
262 did_something = true;
263 while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, in_param) == true)
264 did_something = true;
265 children[0]->detectSignWidth(backup_width_hint, backup_sign_hint);
266 children[1]->detectSignWidth(width_hint, sign_hint);
267 width_hint = std::max(width_hint, backup_width_hint);
268 child_0_is_self_determined = true;
269 break;
270
271 case AST_PARAMETER:
272 case AST_LOCALPARAM:
273 while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true)
274 did_something = true;
275 children[0]->detectSignWidth(width_hint, sign_hint);
276 if (children.size() > 1 && children[1]->type == AST_RANGE) {
277 while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true)
278 did_something = true;
279 if (!children[1]->range_valid)
280 log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum);
281 width_hint = std::max(width_hint, children[1]->range_left - children[1]->range_right + 1);
282 }
283 break;
284
285 case AST_TO_BITS:
286 case AST_TO_SIGNED:
287 case AST_TO_UNSIGNED:
288 case AST_CONCAT:
289 case AST_REPLICATE:
290 case AST_REDUCE_AND:
291 case AST_REDUCE_OR:
292 case AST_REDUCE_XOR:
293 case AST_REDUCE_XNOR:
294 case AST_REDUCE_BOOL:
295 detect_width_simple = true;
296 children_are_self_determined = true;
297 break;
298
299 case AST_NEG:
300 case AST_BIT_NOT:
301 case AST_POS:
302 case AST_BIT_AND:
303 case AST_BIT_OR:
304 case AST_BIT_XOR:
305 case AST_BIT_XNOR:
306 case AST_ADD:
307 case AST_SUB:
308 case AST_MUL:
309 case AST_DIV:
310 case AST_MOD:
311 detect_width_simple = true;
312 break;
313
314 case AST_SHIFT_LEFT:
315 case AST_SHIFT_RIGHT:
316 case AST_SHIFT_SLEFT:
317 case AST_SHIFT_SRIGHT:
318 case AST_POW:
319 detect_width_simple = true;
320 child_1_is_self_determined = true;
321 break;
322
323 case AST_LT:
324 case AST_LE:
325 case AST_EQ:
326 case AST_NE:
327 case AST_EQX:
328 case AST_NEX:
329 case AST_GE:
330 case AST_GT:
331 width_hint = -1;
332 sign_hint = true;
333 for (auto child : children) {
334 while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true)
335 did_something = true;
336 child->detectSignWidthWorker(width_hint, sign_hint);
337 }
338 reset_width_after_children = true;
339 break;
340
341 case AST_LOGIC_AND:
342 case AST_LOGIC_OR:
343 case AST_LOGIC_NOT:
344 detect_width_simple = true;
345 children_are_self_determined = true;
346 break;
347
348 case AST_TERNARY:
349 detect_width_simple = true;
350 child_0_is_self_determined = true;
351 break;
352
353 case AST_MEMRD:
354 detect_width_simple = true;
355 children_are_self_determined = true;
356 break;
357
358 default:
359 width_hint = -1;
360 sign_hint = false;
361 }
362
363 if (detect_width_simple && width_hint < 0) {
364 if (type == AST_REPLICATE)
365 while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, true) == true)
366 did_something = true;
367 for (auto child : children)
368 while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true)
369 did_something = true;
370 detectSignWidth(width_hint, sign_hint);
371 }
372
373 if (type == AST_TERNARY) {
374 int width_hint_left, width_hint_right;
375 bool sign_hint_left, sign_hint_right;
376 bool found_real_left, found_real_right;
377 children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left);
378 children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right);
379 if (found_real_left || found_real_right) {
380 child_1_is_self_determined = true;
381 child_2_is_self_determined = true;
382 }
383 }
384
385 // simplify all children first
386 // (iterate by index as e.g. auto wires can add new children in the process)
387 for (size_t i = 0; i < children.size(); i++) {
388 bool did_something_here = true;
389 if ((type == AST_GENFOR || type == AST_FOR) && i >= 3)
390 break;
391 if ((type == AST_GENIF || type == AST_GENCASE) && i >= 1)
392 break;
393 if (type == AST_GENBLOCK)
394 break;
395 if (type == AST_BLOCK && !str.empty())
396 break;
397 if (type == AST_PREFIX && i >= 1)
398 break;
399 while (did_something_here && i < children.size()) {
400 bool const_fold_here = const_fold, in_lvalue_here = in_lvalue;
401 int width_hint_here = width_hint;
402 bool sign_hint_here = sign_hint;
403 bool in_param_here = in_param;
404 if (i == 0 && (type == AST_REPLICATE || type == AST_WIRE))
405 const_fold_here = true, in_param_here = true;
406 if (type == AST_PARAMETER || type == AST_LOCALPARAM)
407 const_fold_here = true;
408 if (i == 0 && (type == AST_ASSIGN || type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE))
409 in_lvalue_here = true;
410 if (type == AST_BLOCK) {
411 current_block = this;
412 current_block_child = children[i];
413 }
414 if ((type == AST_ALWAYS || type == AST_INITIAL) && children[i]->type == AST_BLOCK)
415 current_top_block = children[i];
416 if (i == 0 && child_0_is_self_determined)
417 width_hint_here = -1, sign_hint_here = false;
418 if (i == 1 && child_1_is_self_determined)
419 width_hint_here = -1, sign_hint_here = false;
420 if (i == 2 && child_2_is_self_determined)
421 width_hint_here = -1, sign_hint_here = false;
422 if (children_are_self_determined)
423 width_hint_here = -1, sign_hint_here = false;
424 did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param_here);
425 if (did_something_here)
426 did_something = true;
427 }
428 if (stage == 2 && children[i]->type == AST_INITIAL && current_ast_mod != this) {
429 current_ast_mod->children.push_back(children[i]);
430 children.erase(children.begin() + (i--));
431 did_something = true;
432 }
433 }
434 for (auto &attr : attributes) {
435 while (attr.second->simplify(true, false, false, stage, -1, false, true))
436 did_something = true;
437 }
438
439 if (reset_width_after_children) {
440 width_hint = backup_width_hint;
441 sign_hint = backup_sign_hint;
442 if (width_hint < 0)
443 detectSignWidth(width_hint, sign_hint);
444 }
445
446 current_block = backup_current_block;
447 current_block_child = backup_current_block_child;
448 current_top_block = backup_current_top_block;
449
450 for (auto it = backup_scope.begin(); it != backup_scope.end(); it++) {
451 if (it->second == NULL)
452 current_scope.erase(it->first);
453 else
454 current_scope[it->first] = it->second;
455 }
456
457 current_filename = filename;
458 set_line_num(linenum);
459
460 if (type == AST_MODULE)
461 current_scope.clear();
462
463 // convert defparam nodes to cell parameters
464 if (type == AST_DEFPARAM && !str.empty()) {
465 size_t pos = str.rfind('.');
466 if (pos == std::string::npos)
467 log_error("Defparam `%s' does not contain a dot (module/parameter seperator) at %s:%d!\n",
468 RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum);
469 std::string modname = str.substr(0, pos), paraname = "\\" + str.substr(pos+1);
470 if (current_scope.count(modname) == 0 || current_scope.at(modname)->type != AST_CELL)
471 log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paraname).c_str(), filename.c_str(), linenum);
472 AstNode *cell = current_scope.at(modname), *paraset = clone();
473 cell->children.insert(cell->children.begin() + 1, paraset);
474 paraset->type = AST_PARASET;
475 paraset->str = paraname;
476 str.clear();
477 }
478
479 // resolve constant prefixes
480 if (type == AST_PREFIX) {
481 if (children[0]->type != AST_CONSTANT) {
482 // dumpAst(NULL, "> ");
483 log_error("Index in generate block prefix syntax at %s:%d is not constant!\n", filename.c_str(), linenum);
484 }
485 log_assert(children[1]->type == AST_IDENTIFIER);
486 newNode = children[1]->clone();
487 const char *second_part = children[1]->str.c_str();
488 if (second_part[0] == '\\')
489 second_part++;
490 newNode->str = stringf("%s[%d].%s", str.c_str(), children[0]->integer, second_part);
491 goto apply_newNode;
492 }
493
494 // evaluate TO_BITS nodes
495 if (type == AST_TO_BITS) {
496 if (children[0]->type != AST_CONSTANT)
497 log_error("Left operand of to_bits expression is not constant at %s:%d!\n", filename.c_str(), linenum);
498 if (children[1]->type != AST_CONSTANT)
499 log_error("Right operand of to_bits expression is not constant at %s:%d!\n", filename.c_str(), linenum);
500 RTLIL::Const new_value = children[1]->bitsAsConst(children[0]->bitsAsConst().as_int(), children[1]->is_signed);
501 newNode = mkconst_bits(new_value.bits, children[1]->is_signed);
502 goto apply_newNode;
503 }
504
505 // annotate constant ranges
506 if (type == AST_RANGE) {
507 bool old_range_valid = range_valid;
508 range_valid = false;
509 range_swapped = false;
510 range_left = -1;
511 range_right = 0;
512 log_assert(children.size() >= 1);
513 if (children[0]->type == AST_CONSTANT) {
514 range_valid = true;
515 range_left = children[0]->integer;
516 if (children.size() == 1)
517 range_right = range_left;
518 }
519 if (children.size() >= 2) {
520 if (children[1]->type == AST_CONSTANT)
521 range_right = children[1]->integer;
522 else
523 range_valid = false;
524 }
525 if (old_range_valid != range_valid)
526 did_something = true;
527 if (range_valid && range_left >= 0 && range_right > range_left) {
528 int tmp = range_right;
529 range_right = range_left;
530 range_left = tmp;
531 range_swapped = true;
532 }
533 }
534
535 // annotate wires with their ranges
536 if (type == AST_WIRE) {
537 if (children.size() > 0) {
538 if (children[0]->range_valid) {
539 if (!range_valid)
540 did_something = true;
541 range_valid = true;
542 range_swapped = children[0]->range_swapped;
543 range_left = children[0]->range_left;
544 range_right = children[0]->range_right;
545 }
546 } else {
547 if (!range_valid)
548 did_something = true;
549 range_valid = true;
550 range_swapped = false;
551 range_left = 0;
552 range_right = 0;
553 }
554 }
555
556 // resolve multiranges on memory decl
557 if (type == AST_MEMORY && children.size() > 1 && children[1]->type == AST_MULTIRANGE)
558 {
559 int total_size = 1;
560 multirange_dimensions.clear();
561 for (auto range : children[1]->children) {
562 if (!range->range_valid)
563 log_error("Non-constant range on memory decl at %s:%d.\n", filename.c_str(), linenum);
564 multirange_dimensions.push_back(std::min(range->range_left, range->range_right));
565 multirange_dimensions.push_back(std::max(range->range_left, range->range_right) - std::min(range->range_left, range->range_right) + 1);
566 total_size *= multirange_dimensions.back();
567 }
568 delete children[1];
569 children[1] = new AstNode(AST_RANGE, AstNode::mkconst_int(0, true), AstNode::mkconst_int(total_size-1, true));
570 did_something = true;
571 }
572
573 // resolve multiranges on memory access
574 if (type == AST_IDENTIFIER && id2ast && id2ast->type == AST_MEMORY && children.size() > 0 && children[0]->type == AST_MULTIRANGE)
575 {
576 AstNode *index_expr = nullptr;
577
578 for (int i = 0; 2*i < SIZE(id2ast->multirange_dimensions); i++)
579 {
580 if (SIZE(children[0]->children) < i)
581 log_error("Insufficient number of array indices for %s at %s:%d.\n", log_id(str), filename.c_str(), linenum);
582
583 AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone();
584
585 if (id2ast->multirange_dimensions[2*i])
586 new_index_expr = new AstNode(AST_SUB, new_index_expr, AstNode::mkconst_int(id2ast->multirange_dimensions[2*i], true));
587
588 if (i == 0)
589 index_expr = new_index_expr;
590 else
591 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);
592 }
593
594 for (int i = SIZE(id2ast->multirange_dimensions)/1; i < SIZE(children[0]->children); i++)
595 children.push_back(children[0]->children[i]->clone());
596
597 delete children[0];
598 if (index_expr == nullptr)
599 children.erase(children.begin());
600 else
601 children[0] = new AstNode(AST_RANGE, index_expr);
602
603 did_something = true;
604 }
605
606 // trim/extend parameters
607 if (type == AST_PARAMETER || type == AST_LOCALPARAM) {
608 if (children.size() > 1 && children[1]->type == AST_RANGE) {
609 if (!children[1]->range_valid)
610 log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum);
611 int width = children[1]->range_left - children[1]->range_right + 1;
612 if (children[0]->type == AST_REALVALUE) {
613 RTLIL::Const constvalue = children[0]->realAsConst(width);
614 log("Warning: converting real value %e to binary %s at %s:%d.\n",
615 children[0]->realvalue, log_signal(constvalue), filename.c_str(), linenum);
616 delete children[0];
617 children[0] = mkconst_bits(constvalue.bits, sign_hint);
618 did_something = true;
619 }
620 if (children[0]->type == AST_CONSTANT) {
621 if (width != int(children[0]->bits.size())) {
622 RTLIL::SigSpec sig(children[0]->bits);
623 sig.extend_u0(width, children[0]->is_signed);
624 AstNode *old_child_0 = children[0];
625 children[0] = mkconst_bits(sig.as_const().bits, children[0]->is_signed);
626 delete old_child_0;
627 }
628 children[0]->is_signed = is_signed;
629 }
630 range_valid = true;
631 range_swapped = children[1]->range_swapped;
632 range_left = children[1]->range_left;
633 range_right = children[1]->range_right;
634 } else
635 if (children.size() > 1 && children[1]->type == AST_REALVALUE && children[0]->type == AST_CONSTANT) {
636 double as_realvalue = children[0]->asReal(sign_hint);
637 delete children[0];
638 children[0] = new AstNode(AST_REALVALUE);
639 children[0]->realvalue = as_realvalue;
640 did_something = true;
641 }
642 }
643
644 // annotate identifiers using scope resolution and create auto-wires as needed
645 if (type == AST_IDENTIFIER) {
646 if (current_scope.count(str) == 0) {
647 for (auto node : current_ast_mod->children) {
648 if ((node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
649 node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK) && str == node->str) {
650 current_scope[node->str] = node;
651 break;
652 }
653 }
654 }
655 if (current_scope.count(str) == 0) {
656 // log("Warning: Creating auto-wire `%s' in module `%s'.\n", str.c_str(), current_ast_mod->str.c_str());
657 AstNode *auto_wire = new AstNode(AST_AUTOWIRE);
658 auto_wire->str = str;
659 current_ast_mod->children.push_back(auto_wire);
660 current_scope[str] = auto_wire;
661 did_something = true;
662 }
663 if (id2ast != current_scope[str]) {
664 id2ast = current_scope[str];
665 did_something = true;
666 }
667 }
668
669 // split memory access with bit select to individual statements
670 if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE && !in_lvalue)
671 {
672 if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1)
673 log_error("Invalid bit-select on memory access at %s:%d!\n", filename.c_str(), linenum);
674
675 int mem_width, mem_size, addr_bits;
676 id2ast->meminfo(mem_width, mem_size, addr_bits);
677
678 std::stringstream sstr;
679 sstr << "$mem2bits$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++);
680 std::string wire_id = sstr.str();
681
682 AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
683 wire->str = wire_id;
684 if (current_block)
685 wire->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
686 current_ast_mod->children.push_back(wire);
687 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
688
689 AstNode *data = clone();
690 delete data->children[1];
691 data->children.pop_back();
692
693 AstNode *assign = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), data);
694 assign->children[0]->str = wire_id;
695
696 if (current_block)
697 {
698 size_t assign_idx = 0;
699 while (assign_idx < current_block->children.size() && current_block->children[assign_idx] != current_block_child)
700 assign_idx++;
701 log_assert(assign_idx < current_block->children.size());
702 current_block->children.insert(current_block->children.begin()+assign_idx, assign);
703 wire->is_reg = true;
704 }
705 else
706 {
707 AstNode *proc = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
708 proc->children[0]->children.push_back(assign);
709 current_ast_mod->children.push_back(proc);
710 }
711
712 newNode = new AstNode(AST_IDENTIFIER, children[1]->clone());
713 newNode->str = wire_id;
714 newNode->id2ast = wire;
715 goto apply_newNode;
716 }
717
718 if (type == AST_WHILE)
719 log_error("While loops are only allowed in constant functions at %s:%d!\n", filename.c_str(), linenum);
720
721 if (type == AST_REPEAT)
722 log_error("Repeat loops are only allowed in constant functions at %s:%d!\n", filename.c_str(), linenum);
723
724 // unroll for loops and generate-for blocks
725 if ((type == AST_GENFOR || type == AST_FOR) && children.size() != 0)
726 {
727 AstNode *init_ast = children[0];
728 AstNode *while_ast = children[1];
729 AstNode *next_ast = children[2];
730 AstNode *body_ast = children[3];
731
732 while (body_ast->type == AST_GENBLOCK && body_ast->str.empty() &&
733 body_ast->children.size() == 1 && body_ast->children.at(0)->type == AST_GENBLOCK)
734 body_ast = body_ast->children.at(0);
735
736 if (init_ast->type != AST_ASSIGN_EQ)
737 log_error("Unsupported 1st expression of generate for-loop at %s:%d!\n", filename.c_str(), linenum);
738 if (next_ast->type != AST_ASSIGN_EQ)
739 log_error("Unsupported 3rd expression of generate for-loop at %s:%d!\n", filename.c_str(), linenum);
740
741 if (type == AST_GENFOR) {
742 if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_GENVAR)
743 log_error("Left hand side of 1st expression of generate for-loop at %s:%d is not a gen var!\n", filename.c_str(), linenum);
744 if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_GENVAR)
745 log_error("Left hand side of 3rd expression of generate for-loop at %s:%d is not a gen var!\n", filename.c_str(), linenum);
746 } else {
747 if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_WIRE)
748 log_error("Left hand side of 1st expression of generate for-loop at %s:%d is not a register!\n", filename.c_str(), linenum);
749 if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_WIRE)
750 log_error("Left hand side of 3rd expression of generate for-loop at %s:%d is not a register!\n", filename.c_str(), linenum);
751 }
752
753 if (init_ast->children[0]->id2ast != next_ast->children[0]->id2ast)
754 log_error("Incompatible left-hand sides in 1st and 3rd expression of generate for-loop at %s:%d!\n", filename.c_str(), linenum);
755
756 // eval 1st expression
757 AstNode *varbuf = init_ast->children[1]->clone();
758 while (varbuf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
759
760 if (varbuf->type != AST_CONSTANT)
761 log_error("Right hand side of 1st expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum);
762
763 varbuf = new AstNode(AST_LOCALPARAM, varbuf);
764 varbuf->str = init_ast->children[0]->str;
765
766 AstNode *backup_scope_varbuf = current_scope[varbuf->str];
767 current_scope[varbuf->str] = varbuf;
768
769 size_t current_block_idx = 0;
770 if (type == AST_FOR) {
771 while (current_block_idx < current_block->children.size() &&
772 current_block->children[current_block_idx] != current_block_child)
773 current_block_idx++;
774 }
775
776 while (1)
777 {
778 // eval 2nd expression
779 AstNode *buf = while_ast->clone();
780 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
781
782 if (buf->type != AST_CONSTANT)
783 log_error("2nd expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum);
784
785 if (buf->integer == 0) {
786 delete buf;
787 break;
788 }
789 delete buf;
790
791 // expand body
792 int index = varbuf->children[0]->integer;
793 if (body_ast->type == AST_GENBLOCK)
794 buf = body_ast->clone();
795 else
796 buf = new AstNode(AST_GENBLOCK, body_ast->clone());
797 if (buf->str.empty()) {
798 std::stringstream sstr;
799 sstr << "$genblock$" << filename << ":" << linenum << "$" << (autoidx++);
800 buf->str = sstr.str();
801 }
802 std::map<std::string, std::string> name_map;
803 std::stringstream sstr;
804 sstr << buf->str << "[" << index << "].";
805 buf->expand_genblock(varbuf->str, sstr.str(), name_map);
806
807 if (type == AST_GENFOR) {
808 for (size_t i = 0; i < buf->children.size(); i++) {
809 buf->children[i]->simplify(false, false, false, stage, -1, false, false);
810 current_ast_mod->children.push_back(buf->children[i]);
811 }
812 } else {
813 for (size_t i = 0; i < buf->children.size(); i++)
814 current_block->children.insert(current_block->children.begin() + current_block_idx++, buf->children[i]);
815 }
816 buf->children.clear();
817 delete buf;
818
819 // eval 3rd expression
820 buf = next_ast->children[1]->clone();
821 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
822
823 if (buf->type != AST_CONSTANT)
824 log_error("Right hand side of 3rd expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum);
825
826 delete varbuf->children[0];
827 varbuf->children[0] = buf;
828 }
829
830 current_scope[varbuf->str] = backup_scope_varbuf;
831 delete varbuf;
832 delete_children();
833 did_something = true;
834 }
835
836 // transform block with name
837 if (type == AST_BLOCK && !str.empty())
838 {
839 std::map<std::string, std::string> name_map;
840 expand_genblock(std::string(), str + ".", name_map);
841
842 std::vector<AstNode*> new_children;
843 for (size_t i = 0; i < children.size(); i++)
844 if (children[i]->type == AST_WIRE) {
845 children[i]->simplify(false, false, false, stage, -1, false, false);
846 current_ast_mod->children.push_back(children[i]);
847 current_scope[children[i]->str] = children[i];
848 } else
849 new_children.push_back(children[i]);
850
851 children.swap(new_children);
852 did_something = true;
853 str.clear();
854 }
855
856 // simplify unconditional generate block
857 if (type == AST_GENBLOCK && children.size() != 0)
858 {
859 if (!str.empty()) {
860 std::map<std::string, std::string> name_map;
861 expand_genblock(std::string(), str + ".", name_map);
862 }
863
864 for (size_t i = 0; i < children.size(); i++) {
865 children[i]->simplify(false, false, false, stage, -1, false, false);
866 current_ast_mod->children.push_back(children[i]);
867 }
868
869 children.clear();
870 did_something = true;
871 }
872
873 // simplify generate-if blocks
874 if (type == AST_GENIF && children.size() != 0)
875 {
876 AstNode *buf = children[0]->clone();
877 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
878 if (buf->type != AST_CONSTANT) {
879 // for (auto f : log_files)
880 // dumpAst(f, "verilog-ast> ");
881 log_error("Condition for generate if at %s:%d is not constant!\n", filename.c_str(), linenum);
882 }
883 if (buf->asBool() != 0) {
884 delete buf;
885 buf = children[1]->clone();
886 } else {
887 delete buf;
888 buf = children.size() > 2 ? children[2]->clone() : NULL;
889 }
890
891 if (buf)
892 {
893 if (buf->type != AST_GENBLOCK)
894 buf = new AstNode(AST_GENBLOCK, buf);
895
896 if (!buf->str.empty()) {
897 std::map<std::string, std::string> name_map;
898 buf->expand_genblock(std::string(), buf->str + ".", name_map);
899 }
900
901 for (size_t i = 0; i < buf->children.size(); i++) {
902 buf->children[i]->simplify(false, false, false, stage, -1, false, false);
903 current_ast_mod->children.push_back(buf->children[i]);
904 }
905
906 buf->children.clear();
907 delete buf;
908 }
909
910 delete_children();
911 did_something = true;
912 }
913
914 // simplify generate-case blocks
915 if (type == AST_GENCASE && children.size() != 0)
916 {
917 AstNode *buf = children[0]->clone();
918 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
919 if (buf->type != AST_CONSTANT) {
920 // for (auto f : log_files)
921 // dumpAst(f, "verilog-ast> ");
922 log_error("Condition for generate case at %s:%d is not constant!\n", filename.c_str(), linenum);
923 }
924
925 bool ref_signed = buf->is_signed;
926 RTLIL::Const ref_value = buf->bitsAsConst();
927 delete buf;
928
929 AstNode *selected_case = NULL;
930 for (size_t i = 1; i < children.size(); i++)
931 {
932 log_assert(children.at(i)->type == AST_COND);
933
934 AstNode *this_genblock = NULL;
935 for (auto child : children.at(i)->children) {
936 log_assert(this_genblock == NULL);
937 if (child->type == AST_GENBLOCK)
938 this_genblock = child;
939 }
940
941 for (auto child : children.at(i)->children)
942 {
943 if (child->type == AST_DEFAULT) {
944 if (selected_case == NULL)
945 selected_case = this_genblock;
946 continue;
947 }
948 if (child->type == AST_GENBLOCK)
949 continue;
950
951 buf = child->clone();
952 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
953 if (buf->type != AST_CONSTANT) {
954 // for (auto f : log_files)
955 // dumpAst(f, "verilog-ast> ");
956 log_error("Expression in generate case at %s:%d is not constant!\n", filename.c_str(), linenum);
957 }
958
959 bool is_selected = RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool();
960 delete buf;
961
962 if (is_selected) {
963 selected_case = this_genblock;
964 i = children.size();
965 break;
966 }
967 }
968 }
969
970 if (selected_case != NULL)
971 {
972 log_assert(selected_case->type == AST_GENBLOCK);
973 buf = selected_case->clone();
974
975 if (!buf->str.empty()) {
976 std::map<std::string, std::string> name_map;
977 buf->expand_genblock(std::string(), buf->str + ".", name_map);
978 }
979
980 for (size_t i = 0; i < buf->children.size(); i++) {
981 buf->children[i]->simplify(false, false, false, stage, -1, false, false);
982 current_ast_mod->children.push_back(buf->children[i]);
983 }
984
985 buf->children.clear();
986 delete buf;
987 }
988
989 delete_children();
990 did_something = true;
991 }
992
993 // unroll cell arrays
994 if (type == AST_CELLARRAY)
995 {
996 if (!children.at(0)->range_valid)
997 log_error("Non-constant array range on cell array at %s:%d.\n", filename.c_str(), linenum);
998
999 newNode = new AstNode(AST_GENBLOCK);
1000 int num = std::max(children.at(0)->range_left, children.at(0)->range_right) - std::min(children.at(0)->range_left, children.at(0)->range_right) + 1;
1001
1002 for (int i = 0; i < num; i++) {
1003 int idx = children.at(0)->range_left > children.at(0)->range_right ? children.at(0)->range_right + i : children.at(0)->range_right - i;
1004 AstNode *new_cell = children.at(1)->clone();
1005 newNode->children.push_back(new_cell);
1006 new_cell->str += stringf("[%d]", idx);
1007 if (new_cell->type == AST_PRIMITIVE) {
1008 log_error("Cell arrays of primitives are currently not supported at %s:%d.\n", filename.c_str(), linenum);
1009 } else {
1010 log_assert(new_cell->children.at(0)->type == AST_CELLTYPE);
1011 new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str.c_str());
1012 }
1013 }
1014
1015 goto apply_newNode;
1016 }
1017
1018 // replace primitives with assignmens
1019 if (type == AST_PRIMITIVE)
1020 {
1021 if (children.size() < 2)
1022 log_error("Insufficient number of arguments for primitive `%s' at %s:%d!\n",
1023 str.c_str(), filename.c_str(), linenum);
1024
1025 std::vector<AstNode*> children_list;
1026 for (auto child : children) {
1027 log_assert(child->type == AST_ARGUMENT);
1028 log_assert(child->children.size() == 1);
1029 children_list.push_back(child->children[0]);
1030 child->children.clear();
1031 delete child;
1032 }
1033 children.clear();
1034
1035 if (str == "bufif0" || str == "bufif1" || str == "notif0" || str == "notif1")
1036 {
1037 if (children_list.size() != 3)
1038 log_error("Invalid number of arguments for primitive `%s' at %s:%d!\n",
1039 str.c_str(), filename.c_str(), linenum);
1040
1041 std::vector<RTLIL::State> z_const(1, RTLIL::State::Sz);
1042
1043 AstNode *mux_input = children_list.at(1);
1044 if (str == "notif0" || str == "notif1") {
1045 mux_input = new AstNode(AST_BIT_NOT, mux_input);
1046 }
1047 AstNode *node = new AstNode(AST_TERNARY, children_list.at(2));
1048 if (str == "bufif0") {
1049 node->children.push_back(AstNode::mkconst_bits(z_const, false));
1050 node->children.push_back(mux_input);
1051 } else {
1052 node->children.push_back(mux_input);
1053 node->children.push_back(AstNode::mkconst_bits(z_const, false));
1054 }
1055
1056 str.clear();
1057 type = AST_ASSIGN;
1058 children.push_back(children_list.at(0));
1059 children.push_back(node);
1060 did_something = true;
1061 }
1062 else
1063 {
1064 AstNodeType op_type = AST_NONE;
1065 bool invert_results = false;
1066
1067 if (str == "and")
1068 op_type = AST_BIT_AND;
1069 if (str == "nand")
1070 op_type = AST_BIT_AND, invert_results = true;
1071 if (str == "or")
1072 op_type = AST_BIT_OR;
1073 if (str == "nor")
1074 op_type = AST_BIT_OR, invert_results = true;
1075 if (str == "xor")
1076 op_type = AST_BIT_XOR;
1077 if (str == "xnor")
1078 op_type = AST_BIT_XOR, invert_results = true;
1079 if (str == "buf")
1080 op_type = AST_POS;
1081 if (str == "not")
1082 op_type = AST_POS, invert_results = true;
1083 log_assert(op_type != AST_NONE);
1084
1085 AstNode *node = children_list[1];
1086 if (op_type != AST_POS)
1087 for (size_t i = 2; i < children_list.size(); i++)
1088 node = new AstNode(op_type, node, children_list[i]);
1089 if (invert_results)
1090 node = new AstNode(AST_BIT_NOT, node);
1091
1092 str.clear();
1093 type = AST_ASSIGN;
1094 children.push_back(children_list[0]);
1095 children.push_back(node);
1096 did_something = true;
1097 }
1098 }
1099
1100 // replace dynamic ranges in left-hand side expressions (e.g. "foo[bar] <= 1'b1;") with
1101 // a big case block that selects the correct single-bit assignment.
1102 if (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) {
1103 if (children[0]->type != AST_IDENTIFIER || children[0]->children.size() == 0)
1104 goto skip_dynamic_range_lvalue_expansion;
1105 if (children[0]->children[0]->range_valid || did_something)
1106 goto skip_dynamic_range_lvalue_expansion;
1107 if (children[0]->id2ast == NULL || children[0]->id2ast->type != AST_WIRE)
1108 goto skip_dynamic_range_lvalue_expansion;
1109 if (!children[0]->id2ast->range_valid)
1110 goto skip_dynamic_range_lvalue_expansion;
1111 int source_width = children[0]->id2ast->range_left - children[0]->id2ast->range_right + 1;
1112 int result_width = 1;
1113 AstNode *shift_expr = NULL;
1114 AstNode *range = children[0]->children[0];
1115 if (range->children.size() == 1) {
1116 shift_expr = range->children[0]->clone();
1117 } else {
1118 shift_expr = range->children[1]->clone();
1119 AstNode *left_at_zero_ast = range->children[0]->clone();
1120 AstNode *right_at_zero_ast = range->children[1]->clone();
1121 while (left_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { }
1122 while (right_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { }
1123 if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
1124 log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n",
1125 str.c_str(), filename.c_str(), linenum);
1126 result_width = left_at_zero_ast->integer - right_at_zero_ast->integer + 1;
1127 }
1128 did_something = true;
1129 newNode = new AstNode(AST_CASE, shift_expr);
1130 for (int i = 0; i <= source_width-result_width; i++) {
1131 int start_bit = children[0]->id2ast->range_right + i;
1132 AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit, true));
1133 AstNode *lvalue = children[0]->clone();
1134 lvalue->delete_children();
1135 lvalue->children.push_back(new AstNode(AST_RANGE,
1136 mkconst_int(start_bit+result_width-1, true), mkconst_int(start_bit, true)));
1137 cond->children.push_back(new AstNode(AST_BLOCK, new AstNode(type, lvalue, children[1]->clone())));
1138 newNode->children.push_back(cond);
1139 }
1140 goto apply_newNode;
1141 }
1142 skip_dynamic_range_lvalue_expansion:;
1143
1144 if (stage > 1 && type == AST_ASSERT && current_block != NULL)
1145 {
1146 std::stringstream sstr;
1147 sstr << "$assert$" << filename << ":" << linenum << "$" << (autoidx++);
1148 std::string id_check = sstr.str() + "_CHECK", id_en = sstr.str() + "_EN";
1149
1150 AstNode *wire_check = new AstNode(AST_WIRE);
1151 wire_check->str = id_check;
1152 current_ast_mod->children.push_back(wire_check);
1153 current_scope[wire_check->str] = wire_check;
1154 while (wire_check->simplify(true, false, false, 1, -1, false, false)) { }
1155
1156 AstNode *wire_en = new AstNode(AST_WIRE);
1157 wire_en->str = id_en;
1158 current_ast_mod->children.push_back(wire_en);
1159 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)))));
1160 current_ast_mod->children.back()->children[0]->children[0]->children[0]->str = id_en;
1161 current_scope[wire_en->str] = wire_en;
1162 while (wire_en->simplify(true, false, false, 1, -1, false, false)) { }
1163
1164 std::vector<RTLIL::State> x_bit;
1165 x_bit.push_back(RTLIL::State::Sx);
1166
1167 AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bit, false));
1168 assign_check->children[0]->str = id_check;
1169
1170 AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, 1));
1171 assign_en->children[0]->str = id_en;
1172
1173 AstNode *default_signals = new AstNode(AST_BLOCK);
1174 default_signals->children.push_back(assign_check);
1175 default_signals->children.push_back(assign_en);
1176 current_top_block->children.insert(current_top_block->children.begin(), default_signals);
1177
1178 assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone()));
1179 assign_check->children[0]->str = id_check;
1180
1181 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(1, false, 1));
1182 assign_en->children[0]->str = id_en;
1183
1184 newNode = new AstNode(AST_BLOCK);
1185 newNode->children.push_back(assign_check);
1186 newNode->children.push_back(assign_en);
1187
1188 AstNode *assertnode = new AstNode(AST_ASSERT);
1189 assertnode->children.push_back(new AstNode(AST_IDENTIFIER));
1190 assertnode->children.push_back(new AstNode(AST_IDENTIFIER));
1191 assertnode->children[0]->str = id_check;
1192 assertnode->children[1]->str = id_en;
1193 assertnode->attributes.swap(attributes);
1194 current_ast_mod->children.push_back(assertnode);
1195
1196 goto apply_newNode;
1197 }
1198
1199 if (stage > 1 && type == AST_ASSERT && children.size() == 1)
1200 {
1201 children[0] = new AstNode(AST_REDUCE_BOOL, children[0]->clone());
1202 children.push_back(mkconst_int(1, false, 1));
1203 did_something = true;
1204 }
1205
1206 // found right-hand side identifier for memory -> replace with memory read port
1207 if (stage > 1 && type == AST_IDENTIFIER && id2ast != NULL && id2ast->type == AST_MEMORY && !in_lvalue &&
1208 children[0]->type == AST_RANGE && children[0]->children.size() == 1) {
1209 newNode = new AstNode(AST_MEMRD, children[0]->children[0]->clone());
1210 newNode->str = str;
1211 newNode->id2ast = id2ast;
1212 goto apply_newNode;
1213 }
1214
1215 // assignment with memory in left-hand side expression -> replace with memory write port
1216 if (stage > 1 && (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) && children[0]->type == AST_IDENTIFIER &&
1217 children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY && children[0]->id2ast->children.size() >= 2 &&
1218 children[0]->id2ast->children[0]->range_valid && children[0]->id2ast->children[1]->range_valid &&
1219 (children[0]->children.size() == 1 || children[0]->children.size() == 2) && children[0]->children[0]->type == AST_RANGE)
1220 {
1221 std::stringstream sstr;
1222 sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++);
1223 std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA", id_en = sstr.str() + "_EN";
1224
1225 if (type == AST_ASSIGN_EQ)
1226 log("Warning: Blocking assignment to memory in line %s:%d is handled like a non-blocking assignment.\n",
1227 filename.c_str(), linenum);
1228
1229 int mem_width, mem_size, addr_bits;
1230 children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
1231
1232 AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
1233 wire_addr->str = id_addr;
1234 current_ast_mod->children.push_back(wire_addr);
1235 current_scope[wire_addr->str] = wire_addr;
1236 while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
1237
1238 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
1239 wire_data->str = id_data;
1240 current_ast_mod->children.push_back(wire_data);
1241 current_scope[wire_data->str] = wire_data;
1242 while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
1243
1244 AstNode *wire_en = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
1245 wire_en->str = id_en;
1246 current_ast_mod->children.push_back(wire_en);
1247 current_scope[wire_en->str] = wire_en;
1248 while (wire_en->simplify(true, false, false, 1, -1, false, false)) { }
1249
1250 std::vector<RTLIL::State> x_bits_addr, x_bits_data, set_bits_en;
1251 for (int i = 0; i < addr_bits; i++)
1252 x_bits_addr.push_back(RTLIL::State::Sx);
1253 for (int i = 0; i < mem_width; i++)
1254 x_bits_data.push_back(RTLIL::State::Sx);
1255 for (int i = 0; i < mem_width; i++)
1256 set_bits_en.push_back(RTLIL::State::S1);
1257
1258 AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false));
1259 assign_addr->children[0]->str = id_addr;
1260
1261 AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false));
1262 assign_data->children[0]->str = id_data;
1263
1264 AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width));
1265 assign_en->children[0]->str = id_en;
1266
1267 AstNode *default_signals = new AstNode(AST_BLOCK);
1268 default_signals->children.push_back(assign_addr);
1269 default_signals->children.push_back(assign_data);
1270 default_signals->children.push_back(assign_en);
1271 current_top_block->children.insert(current_top_block->children.begin(), default_signals);
1272
1273 assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());
1274 assign_addr->children[0]->str = id_addr;
1275
1276 if (children[0]->children.size() == 2)
1277 {
1278 if (children[0]->children[1]->range_valid)
1279 {
1280 int offset = children[0]->children[1]->range_right;
1281 int width = children[0]->children[1]->range_left - offset + 1;
1282
1283 std::vector<RTLIL::State> padding_x(offset, RTLIL::State::Sx);
1284
1285 for (int i = 0; i < mem_width; i++)
1286 set_bits_en[i] = offset <= i && i < offset+width ? RTLIL::State::S1 : RTLIL::State::S0;
1287
1288 assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),
1289 new AstNode(AST_CONCAT, mkconst_bits(padding_x, false), children[1]->clone()));
1290 assign_data->children[0]->str = id_data;
1291
1292 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));
1293 assign_en->children[0]->str = id_en;
1294 }
1295 else
1296 {
1297 AstNode *the_range = children[0]->children[1];
1298 AstNode *left_at_zero_ast = the_range->children[0]->clone();
1299 AstNode *right_at_zero_ast = the_range->children.size() >= 2 ? the_range->children[1]->clone() : left_at_zero_ast->clone();
1300 AstNode *offset_ast = right_at_zero_ast->clone();
1301
1302 while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }
1303 while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }
1304 if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
1305 log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str.c_str(), filename.c_str(), linenum);
1306 int width = left_at_zero_ast->integer - right_at_zero_ast->integer + 1;
1307
1308 for (int i = 0; i < mem_width; i++)
1309 set_bits_en[i] = i < width ? RTLIL::State::S1 : RTLIL::State::S0;
1310
1311 assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),
1312 new AstNode(AST_SHIFT_LEFT, children[1]->clone(), offset_ast->clone()));
1313 assign_data->children[0]->str = id_data;
1314
1315 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER),
1316 new AstNode(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone()));
1317 assign_en->children[0]->str = id_en;
1318
1319 delete left_at_zero_ast;
1320 delete right_at_zero_ast;
1321 delete offset_ast;
1322 }
1323 }
1324 else
1325 {
1326 assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone());
1327 assign_data->children[0]->str = id_data;
1328
1329 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));
1330 assign_en->children[0]->str = id_en;
1331 }
1332
1333 newNode = new AstNode(AST_BLOCK);
1334 newNode->children.push_back(assign_addr);
1335 newNode->children.push_back(assign_data);
1336 newNode->children.push_back(assign_en);
1337
1338 AstNode *wrnode = new AstNode(AST_MEMWR);
1339 wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
1340 wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
1341 wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
1342 wrnode->str = children[0]->str;
1343 wrnode->children[0]->str = id_addr;
1344 wrnode->children[1]->str = id_data;
1345 wrnode->children[2]->str = id_en;
1346 current_ast_mod->children.push_back(wrnode);
1347
1348 goto apply_newNode;
1349 }
1350
1351 // replace function and task calls with the code from the function or task
1352 if ((type == AST_FCALL || type == AST_TCALL) && !str.empty())
1353 {
1354 if (type == AST_FCALL)
1355 {
1356 if (str == "\\$clog2")
1357 {
1358 if (children.size() != 1)
1359 log_error("System function %s got %d arguments, expected 1 at %s:%d.\n",
1360 RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum);
1361
1362 AstNode *buf = children[0]->clone();
1363 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1364 if (buf->type != AST_CONSTANT)
1365 log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
1366
1367 RTLIL::Const arg_value = buf->bitsAsConst();
1368 delete buf;
1369
1370 uint32_t result = 0;
1371 for (size_t i = 0; i < arg_value.bits.size(); i++)
1372 if (arg_value.bits.at(i) == RTLIL::State::S1)
1373 result = i;
1374
1375 newNode = mkconst_int(result, false);
1376 goto apply_newNode;
1377 }
1378
1379 if (str == "\\$ln" || str == "\\$log10" || str == "\\$exp" || str == "\\$sqrt" || str == "\\$pow" ||
1380 str == "\\$floor" || str == "\\$ceil" || str == "\\$sin" || str == "\\$cos" || str == "\\$tan" ||
1381 str == "\\$asin" || str == "\\$acos" || str == "\\$atan" || str == "\\$atan2" || str == "\\$hypot" ||
1382 str == "\\$sinh" || str == "\\$cosh" || str == "\\$tanh" || str == "\\$asinh" || str == "\\$acosh" || str == "\\$atanh")
1383 {
1384 bool func_with_two_arguments = str == "\\$pow" || str == "\\$atan2" || str == "\\$hypot";
1385 double x = 0, y = 0;
1386
1387 if (func_with_two_arguments) {
1388 if (children.size() != 2)
1389 log_error("System function %s got %d arguments, expected 2 at %s:%d.\n",
1390 RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum);
1391 } else {
1392 if (children.size() != 1)
1393 log_error("System function %s got %d arguments, expected 1 at %s:%d.\n",
1394 RTLIL::unescape_id(str).c_str(), int(children.size()), filename.c_str(), linenum);
1395 }
1396
1397 if (children.size() >= 1) {
1398 while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1399 if (!children[0]->isConst())
1400 log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n",
1401 RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum);
1402 int child_width_hint = width_hint;
1403 bool child_sign_hint = sign_hint;
1404 children[0]->detectSignWidth(child_width_hint, child_sign_hint);
1405 x = children[0]->asReal(child_sign_hint);
1406 }
1407
1408 if (children.size() >= 2) {
1409 while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
1410 if (!children[1]->isConst())
1411 log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n",
1412 RTLIL::unescape_id(str).c_str(), filename.c_str(), linenum);
1413 int child_width_hint = width_hint;
1414 bool child_sign_hint = sign_hint;
1415 children[1]->detectSignWidth(child_width_hint, child_sign_hint);
1416 y = children[1]->asReal(child_sign_hint);
1417 }
1418
1419 newNode = new AstNode(AST_REALVALUE);
1420 if (str == "\\$ln") newNode->realvalue = ::log(x);
1421 else if (str == "\\$log10") newNode->realvalue = ::log10(x);
1422 else if (str == "\\$exp") newNode->realvalue = ::exp(x);
1423 else if (str == "\\$sqrt") newNode->realvalue = ::sqrt(x);
1424 else if (str == "\\$pow") newNode->realvalue = ::pow(x, y);
1425 else if (str == "\\$floor") newNode->realvalue = ::floor(x);
1426 else if (str == "\\$ceil") newNode->realvalue = ::ceil(x);
1427 else if (str == "\\$sin") newNode->realvalue = ::sin(x);
1428 else if (str == "\\$cos") newNode->realvalue = ::cos(x);
1429 else if (str == "\\$tan") newNode->realvalue = ::tan(x);
1430 else if (str == "\\$asin") newNode->realvalue = ::asin(x);
1431 else if (str == "\\$acos") newNode->realvalue = ::acos(x);
1432 else if (str == "\\$atan") newNode->realvalue = ::atan(x);
1433 else if (str == "\\$atan2") newNode->realvalue = ::atan2(x, y);
1434 else if (str == "\\$hypot") newNode->realvalue = ::hypot(x, y);
1435 else if (str == "\\$sinh") newNode->realvalue = ::sinh(x);
1436 else if (str == "\\$cosh") newNode->realvalue = ::cosh(x);
1437 else if (str == "\\$tanh") newNode->realvalue = ::tanh(x);
1438 else if (str == "\\$asinh") newNode->realvalue = ::asinh(x);
1439 else if (str == "\\$acosh") newNode->realvalue = ::acosh(x);
1440 else if (str == "\\$atanh") newNode->realvalue = ::atanh(x);
1441 else log_abort();
1442 goto apply_newNode;
1443 }
1444
1445 if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION)
1446 log_error("Can't resolve function name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
1447 }
1448 if (type == AST_TCALL) {
1449 if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK)
1450 log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
1451 }
1452
1453 AstNode *decl = current_scope[str];
1454
1455 std::stringstream sstr;
1456 sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++) << "$";
1457 std::string prefix = sstr.str();
1458
1459 bool recommend_const_eval = false;
1460 bool require_const_eval = in_param ? false : has_const_only_constructs(recommend_const_eval);
1461 if ((in_param || recommend_const_eval || require_const_eval) && !decl->attributes.count("\\via_celltype"))
1462 {
1463 bool all_args_const = true;
1464 for (auto child : children) {
1465 while (child->simplify(true, false, false, 1, -1, false, true)) { }
1466 if (child->type != AST_CONSTANT)
1467 all_args_const = false;
1468 }
1469
1470 if (all_args_const) {
1471 AstNode *func_workspace = current_scope[str]->clone();
1472 newNode = func_workspace->eval_const_function(this);
1473 delete func_workspace;
1474 goto apply_newNode;
1475 }
1476
1477 if (in_param)
1478 log_error("Non-constant function call in constant expression at %s:%d.\n", filename.c_str(), linenum);
1479 if (require_const_eval)
1480 log_error("Function %s can only be called with constant arguments at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
1481 }
1482
1483 size_t arg_count = 0;
1484 std::map<std::string, std::string> replace_rules;
1485
1486 if (current_block == NULL)
1487 {
1488 log_assert(type == AST_FCALL);
1489
1490 AstNode *wire = NULL;
1491 for (auto child : decl->children)
1492 if (child->type == AST_WIRE && child->str == str)
1493 wire = child->clone();
1494 log_assert(wire != NULL);
1495
1496 wire->str = prefix + str;
1497 wire->port_id = 0;
1498 wire->is_input = false;
1499 wire->is_output = false;
1500
1501 current_ast_mod->children.push_back(wire);
1502 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
1503
1504 AstNode *lvalue = new AstNode(AST_IDENTIFIER);
1505 lvalue->str = wire->str;
1506
1507 AstNode *always = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK,
1508 new AstNode(AST_ASSIGN_EQ, lvalue, clone())));
1509 current_ast_mod->children.push_back(always);
1510
1511 goto replace_fcall_with_id;
1512 }
1513
1514 if (decl->attributes.count("\\via_celltype"))
1515 {
1516 std::string celltype = decl->attributes.at("\\via_celltype")->asAttrConst().decode_string();
1517 std::string outport = str;
1518
1519 if (celltype.find(' ') != std::string::npos) {
1520 int pos = celltype.find(' ');
1521 outport = RTLIL::escape_id(celltype.substr(pos+1));
1522 celltype = RTLIL::escape_id(celltype.substr(0, pos));
1523 } else
1524 celltype = RTLIL::escape_id(celltype);
1525
1526 AstNode *cell = new AstNode(AST_CELL, new AstNode(AST_CELLTYPE));
1527 cell->str = prefix.substr(0, SIZE(prefix)-1);
1528 cell->children[0]->str = celltype;
1529
1530 for (auto attr : decl->attributes)
1531 if (attr.first.str().rfind("\\via_celltype_defparam_", 0) == 0)
1532 {
1533 AstNode *cell_arg = new AstNode(AST_PARASET, attr.second->clone());
1534 cell_arg->str = RTLIL::escape_id(attr.first.str().substr(strlen("\\via_celltype_defparam_")));
1535 cell->children.push_back(cell_arg);
1536 }
1537
1538 for (auto child : decl->children)
1539 if (child->type == AST_WIRE && (child->is_input || child->is_output || (type == AST_FCALL && child->str == str)))
1540 {
1541 AstNode *wire = child->clone();
1542 wire->str = prefix + wire->str;
1543 wire->port_id = 0;
1544 wire->is_input = false;
1545 wire->is_output = false;
1546 current_ast_mod->children.push_back(wire);
1547 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
1548
1549 AstNode *wire_id = new AstNode(AST_IDENTIFIER);
1550 wire_id->str = wire->str;
1551
1552 if ((child->is_input || child->is_output) && arg_count < children.size())
1553 {
1554 AstNode *arg = children[arg_count++]->clone();
1555 AstNode *assign = child->is_input ?
1556 new AstNode(AST_ASSIGN_EQ, wire_id, arg) :
1557 new AstNode(AST_ASSIGN_EQ, arg, wire_id);
1558
1559 for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) {
1560 if (*it != current_block_child)
1561 continue;
1562 current_block->children.insert(it, assign);
1563 break;
1564 }
1565 }
1566
1567 AstNode *cell_arg = new AstNode(AST_ARGUMENT, wire_id->clone());
1568 cell_arg->str = child->str == str ? outport : child->str;
1569 cell->children.push_back(cell_arg);
1570 }
1571
1572 current_ast_mod->children.push_back(cell);
1573 goto replace_fcall_with_id;
1574 }
1575
1576 for (auto child : decl->children)
1577 if (child->type == AST_WIRE)
1578 {
1579 AstNode *wire = child->clone();
1580 wire->str = prefix + wire->str;
1581 wire->port_id = 0;
1582 wire->is_input = false;
1583 wire->is_output = false;
1584 current_ast_mod->children.push_back(wire);
1585 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
1586
1587 replace_rules[child->str] = wire->str;
1588
1589 if ((child->is_input || child->is_output) && arg_count < children.size())
1590 {
1591 AstNode *arg = children[arg_count++]->clone();
1592 AstNode *wire_id = new AstNode(AST_IDENTIFIER);
1593 wire_id->str = wire->str;
1594 AstNode *assign = child->is_input ?
1595 new AstNode(AST_ASSIGN_EQ, wire_id, arg) :
1596 new AstNode(AST_ASSIGN_EQ, arg, wire_id);
1597
1598 for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) {
1599 if (*it != current_block_child)
1600 continue;
1601 current_block->children.insert(it, assign);
1602 break;
1603 }
1604 }
1605 }
1606
1607 for (auto child : decl->children)
1608 if (child->type != AST_WIRE)
1609 {
1610 AstNode *stmt = child->clone();
1611 stmt->replace_ids(prefix, replace_rules);
1612
1613 for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) {
1614 if (*it != current_block_child)
1615 continue;
1616 current_block->children.insert(it, stmt);
1617 break;
1618 }
1619 }
1620
1621 replace_fcall_with_id:
1622 if (type == AST_FCALL) {
1623 delete_children();
1624 type = AST_IDENTIFIER;
1625 str = prefix + str;
1626 }
1627 if (type == AST_TCALL)
1628 str = "";
1629 did_something = true;
1630 }
1631
1632 // perform const folding when activated
1633 if (const_fold)
1634 {
1635 bool string_op;
1636 std::vector<RTLIL::State> tmp_bits;
1637 RTLIL::Const (*const_func)(const RTLIL::Const&, const RTLIL::Const&, bool, bool, int);
1638 RTLIL::Const dummy_arg;
1639
1640 switch (type)
1641 {
1642 case AST_IDENTIFIER:
1643 if (current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM)) {
1644 if (current_scope[str]->children[0]->type == AST_CONSTANT) {
1645 if (children.size() != 0 && children[0]->type == AST_RANGE && children[0]->range_valid) {
1646 std::vector<RTLIL::State> data;
1647 bool param_upto = current_scope[str]->range_valid && current_scope[str]->range_swapped;
1648 int param_offset = current_scope[str]->range_valid ? current_scope[str]->range_right : 0;
1649 int param_width = current_scope[str]->range_valid ? current_scope[str]->range_left - current_scope[str]->range_right + 1 :
1650 SIZE(current_scope[str]->children[0]->bits);
1651 int tmp_range_left = children[0]->range_left, tmp_range_right = children[0]->range_right;
1652 if (param_upto) {
1653 tmp_range_left = (param_width + 2*param_offset) - children[0]->range_right - 1;
1654 tmp_range_right = (param_width + 2*param_offset) - children[0]->range_left - 1;
1655 }
1656 for (int i = tmp_range_right; i <= tmp_range_left; i++) {
1657 int index = i - param_offset;
1658 if (0 <= index && index < param_width)
1659 data.push_back(current_scope[str]->children[0]->bits[index]);
1660 else
1661 data.push_back(RTLIL::State::Sx);
1662 }
1663 newNode = mkconst_bits(data, false);
1664 } else
1665 if (children.size() == 0)
1666 newNode = current_scope[str]->children[0]->clone();
1667 } else
1668 if (current_scope[str]->children[0]->isConst())
1669 newNode = current_scope[str]->children[0]->clone();
1670 }
1671 else if (at_zero && current_scope.count(str) > 0 && (current_scope[str]->type == AST_WIRE || current_scope[str]->type == AST_AUTOWIRE)) {
1672 newNode = mkconst_int(0, sign_hint, width_hint);
1673 }
1674 break;
1675 case AST_BIT_NOT:
1676 if (children[0]->type == AST_CONSTANT) {
1677 RTLIL::Const y = RTLIL::const_not(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint);
1678 newNode = mkconst_bits(y.bits, sign_hint);
1679 }
1680 break;
1681 case AST_TO_SIGNED:
1682 case AST_TO_UNSIGNED:
1683 if (children[0]->type == AST_CONSTANT) {
1684 RTLIL::Const y = children[0]->bitsAsConst(width_hint, sign_hint);
1685 newNode = mkconst_bits(y.bits, type == AST_TO_SIGNED);
1686 }
1687 break;
1688 if (0) { case AST_BIT_AND: const_func = RTLIL::const_and; }
1689 if (0) { case AST_BIT_OR: const_func = RTLIL::const_or; }
1690 if (0) { case AST_BIT_XOR: const_func = RTLIL::const_xor; }
1691 if (0) { case AST_BIT_XNOR: const_func = RTLIL::const_xnor; }
1692 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
1693 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
1694 children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint);
1695 newNode = mkconst_bits(y.bits, sign_hint);
1696 }
1697 break;
1698 if (0) { case AST_REDUCE_AND: const_func = RTLIL::const_reduce_and; }
1699 if (0) { case AST_REDUCE_OR: const_func = RTLIL::const_reduce_or; }
1700 if (0) { case AST_REDUCE_XOR: const_func = RTLIL::const_reduce_xor; }
1701 if (0) { case AST_REDUCE_XNOR: const_func = RTLIL::const_reduce_xnor; }
1702 if (0) { case AST_REDUCE_BOOL: const_func = RTLIL::const_reduce_bool; }
1703 if (children[0]->type == AST_CONSTANT) {
1704 RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), dummy_arg, false, false, -1);
1705 newNode = mkconst_bits(y.bits, false);
1706 }
1707 break;
1708 case AST_LOGIC_NOT:
1709 if (children[0]->type == AST_CONSTANT) {
1710 RTLIL::Const y = RTLIL::const_logic_not(RTLIL::Const(children[0]->bits), dummy_arg, children[0]->is_signed, false, -1);
1711 newNode = mkconst_bits(y.bits, false);
1712 } else
1713 if (children[0]->isConst()) {
1714 newNode = mkconst_int(children[0]->asReal(sign_hint) == 0, false, 1);
1715 }
1716 break;
1717 if (0) { case AST_LOGIC_AND: const_func = RTLIL::const_logic_and; }
1718 if (0) { case AST_LOGIC_OR: const_func = RTLIL::const_logic_or; }
1719 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
1720 RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), RTLIL::Const(children[1]->bits),
1721 children[0]->is_signed, children[1]->is_signed, -1);
1722 newNode = mkconst_bits(y.bits, false);
1723 } else
1724 if (children[0]->isConst() && children[1]->isConst()) {
1725 if (type == AST_LOGIC_AND)
1726 newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) && (children[1]->asReal(sign_hint) != 0), false, 1);
1727 else
1728 newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) || (children[1]->asReal(sign_hint) != 0), false, 1);
1729 }
1730 break;
1731 if (0) { case AST_SHIFT_LEFT: const_func = RTLIL::const_shl; }
1732 if (0) { case AST_SHIFT_RIGHT: const_func = RTLIL::const_shr; }
1733 if (0) { case AST_SHIFT_SLEFT: const_func = RTLIL::const_sshl; }
1734 if (0) { case AST_SHIFT_SRIGHT: const_func = RTLIL::const_sshr; }
1735 if (0) { case AST_POW: const_func = RTLIL::const_pow; }
1736 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
1737 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
1738 RTLIL::Const(children[1]->bits), sign_hint, type == AST_POW ? children[1]->is_signed : false, width_hint);
1739 newNode = mkconst_bits(y.bits, sign_hint);
1740 } else
1741 if (type == AST_POW && children[0]->isConst() && children[1]->isConst()) {
1742 newNode = new AstNode(AST_REALVALUE);
1743 newNode->realvalue = pow(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint));
1744 }
1745 break;
1746 if (0) { case AST_LT: const_func = RTLIL::const_lt; }
1747 if (0) { case AST_LE: const_func = RTLIL::const_le; }
1748 if (0) { case AST_EQ: const_func = RTLIL::const_eq; }
1749 if (0) { case AST_NE: const_func = RTLIL::const_ne; }
1750 if (0) { case AST_EQX: const_func = RTLIL::const_eqx; }
1751 if (0) { case AST_NEX: const_func = RTLIL::const_nex; }
1752 if (0) { case AST_GE: const_func = RTLIL::const_ge; }
1753 if (0) { case AST_GT: const_func = RTLIL::const_gt; }
1754 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
1755 int cmp_width = std::max(children[0]->bits.size(), children[1]->bits.size());
1756 bool cmp_signed = children[0]->is_signed && children[1]->is_signed;
1757 RTLIL::Const y = const_func(children[0]->bitsAsConst(cmp_width, cmp_signed),
1758 children[1]->bitsAsConst(cmp_width, cmp_signed), cmp_signed, cmp_signed, 1);
1759 newNode = mkconst_bits(y.bits, false);
1760 } else
1761 if (children[0]->isConst() && children[1]->isConst()) {
1762 bool cmp_signed = (children[0]->type == AST_REALVALUE || children[0]->is_signed) && (children[1]->type == AST_REALVALUE || children[1]->is_signed);
1763 switch (type) {
1764 case AST_LT: newNode = mkconst_int(children[0]->asReal(cmp_signed) < children[1]->asReal(cmp_signed), false, 1); break;
1765 case AST_LE: newNode = mkconst_int(children[0]->asReal(cmp_signed) <= children[1]->asReal(cmp_signed), false, 1); break;
1766 case AST_EQ: newNode = mkconst_int(children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break;
1767 case AST_NE: newNode = mkconst_int(children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break;
1768 case AST_EQX: newNode = mkconst_int(children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break;
1769 case AST_NEX: newNode = mkconst_int(children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break;
1770 case AST_GE: newNode = mkconst_int(children[0]->asReal(cmp_signed) >= children[1]->asReal(cmp_signed), false, 1); break;
1771 case AST_GT: newNode = mkconst_int(children[0]->asReal(cmp_signed) > children[1]->asReal(cmp_signed), false, 1); break;
1772 default: log_abort();
1773 }
1774 }
1775 break;
1776 if (0) { case AST_ADD: const_func = RTLIL::const_add; }
1777 if (0) { case AST_SUB: const_func = RTLIL::const_sub; }
1778 if (0) { case AST_MUL: const_func = RTLIL::const_mul; }
1779 if (0) { case AST_DIV: const_func = RTLIL::const_div; }
1780 if (0) { case AST_MOD: const_func = RTLIL::const_mod; }
1781 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
1782 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
1783 children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint);
1784 newNode = mkconst_bits(y.bits, sign_hint);
1785 } else
1786 if (children[0]->isConst() && children[1]->isConst()) {
1787 newNode = new AstNode(AST_REALVALUE);
1788 switch (type) {
1789 case AST_ADD: newNode->realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint); break;
1790 case AST_SUB: newNode->realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint); break;
1791 case AST_MUL: newNode->realvalue = children[0]->asReal(sign_hint) * children[1]->asReal(sign_hint); break;
1792 case AST_DIV: newNode->realvalue = children[0]->asReal(sign_hint) / children[1]->asReal(sign_hint); break;
1793 case AST_MOD: newNode->realvalue = fmod(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); break;
1794 default: log_abort();
1795 }
1796 }
1797 break;
1798 if (0) { case AST_POS: const_func = RTLIL::const_pos; }
1799 if (0) { case AST_NEG: const_func = RTLIL::const_neg; }
1800 if (children[0]->type == AST_CONSTANT) {
1801 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint);
1802 newNode = mkconst_bits(y.bits, sign_hint);
1803 } else
1804 if (children[0]->isConst()) {
1805 newNode = new AstNode(AST_REALVALUE);
1806 if (type == AST_POS)
1807 newNode->realvalue = +children[0]->asReal(sign_hint);
1808 else
1809 newNode->realvalue = -children[0]->asReal(sign_hint);
1810 }
1811 break;
1812 case AST_CASE:
1813 if (children[0]->type == AST_CONSTANT && children[0]->bits_only_01()) {
1814 std::vector<AstNode*> new_children;
1815 new_children.push_back(children[0]);
1816 for (int i = 1; i < SIZE(children); i++) {
1817 AstNode *child = children[i];
1818 log_assert(child->type == AST_COND);
1819 for (auto v : child->children) {
1820 if (v->type == AST_DEFAULT)
1821 goto keep_const_cond;
1822 if (v->type == AST_BLOCK)
1823 continue;
1824 if (v->type == AST_CONSTANT && v->bits_only_01()) {
1825 if (v->bits == children[0]->bits) {
1826 while (i+1 < SIZE(children))
1827 delete children[++i];
1828 goto keep_const_cond;
1829 }
1830 continue;
1831 }
1832 goto keep_const_cond;
1833 }
1834 if (0)
1835 keep_const_cond:
1836 new_children.push_back(child);
1837 else
1838 delete child;
1839 }
1840 new_children.swap(children);
1841 }
1842 break;
1843 case AST_TERNARY:
1844 if (children[0]->isConst())
1845 {
1846 bool found_sure_true = false;
1847 bool found_maybe_true = false;
1848
1849 if (children[0]->type == AST_CONSTANT)
1850 for (auto &bit : children[0]->bits) {
1851 if (bit == RTLIL::State::S1)
1852 found_sure_true = true;
1853 if (bit > RTLIL::State::S1)
1854 found_maybe_true = true;
1855 }
1856 else
1857 found_sure_true = children[0]->asReal(sign_hint) != 0;
1858
1859 AstNode *choice = NULL, *not_choice = NULL;
1860 if (found_sure_true)
1861 choice = children[1], not_choice = children[2];
1862 else if (!found_maybe_true)
1863 choice = children[2], not_choice = children[1];
1864
1865 if (choice != NULL) {
1866 if (choice->type == AST_CONSTANT) {
1867 int other_width_hint = width_hint;
1868 bool other_sign_hint = sign_hint, other_real = false;
1869 not_choice->detectSignWidth(other_width_hint, other_sign_hint, &other_real);
1870 if (other_real) {
1871 newNode = new AstNode(AST_REALVALUE);
1872 choice->detectSignWidth(width_hint, sign_hint);
1873 newNode->realvalue = choice->asReal(sign_hint);
1874 } else {
1875 RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint);
1876 if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false)
1877 newNode = mkconst_str(y.bits);
1878 else
1879 newNode = mkconst_bits(y.bits, sign_hint);
1880 }
1881 } else
1882 if (choice->isConst()) {
1883 newNode = choice->clone();
1884 }
1885 } else if (children[1]->type == AST_CONSTANT && children[2]->type == AST_CONSTANT) {
1886 RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint);
1887 RTLIL::Const b = children[2]->bitsAsConst(width_hint, sign_hint);
1888 log_assert(a.bits.size() == b.bits.size());
1889 for (size_t i = 0; i < a.bits.size(); i++)
1890 if (a.bits[i] != b.bits[i])
1891 a.bits[i] = RTLIL::State::Sx;
1892 newNode = mkconst_bits(a.bits, sign_hint);
1893 } else if (children[1]->isConst() && children[2]->isConst()) {
1894 newNode = new AstNode(AST_REALVALUE);
1895 if (children[1]->asReal(sign_hint) == children[2]->asReal(sign_hint))
1896 newNode->realvalue = children[1]->asReal(sign_hint);
1897 else
1898 // IEEE Std 1800-2012 Sec. 11.4.11 states that the entry in Table 7-1 for
1899 // the data type in question should be returned if the ?: is ambiguous. The
1900 // value in Table 7-1 for the 'real' type is 0.0.
1901 newNode->realvalue = 0.0;
1902 }
1903 }
1904 break;
1905 case AST_CONCAT:
1906 string_op = !children.empty();
1907 for (auto it = children.begin(); it != children.end(); it++) {
1908 if ((*it)->type != AST_CONSTANT)
1909 goto not_const;
1910 if (!(*it)->is_string)
1911 string_op = false;
1912 tmp_bits.insert(tmp_bits.end(), (*it)->bits.begin(), (*it)->bits.end());
1913 }
1914 newNode = string_op ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false);
1915 break;
1916 case AST_REPLICATE:
1917 if (children.at(0)->type != AST_CONSTANT || children.at(1)->type != AST_CONSTANT)
1918 goto not_const;
1919 for (int i = 0; i < children[0]->bitsAsConst().as_int(); i++)
1920 tmp_bits.insert(tmp_bits.end(), children.at(1)->bits.begin(), children.at(1)->bits.end());
1921 newNode = children.at(1)->is_string ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false);
1922 break;
1923 default:
1924 not_const:
1925 break;
1926 }
1927 }
1928
1929 // if any of the above set 'newNode' -> use 'newNode' as template to update 'this'
1930 if (newNode) {
1931 apply_newNode:
1932 // fprintf(stderr, "----\n");
1933 // dumpAst(stderr, "- ");
1934 // newNode->dumpAst(stderr, "+ ");
1935 log_assert(newNode != NULL);
1936 newNode->filename = filename;
1937 newNode->linenum = linenum;
1938 newNode->cloneInto(this);
1939 delete newNode;
1940 did_something = true;
1941 }
1942
1943 if (!did_something)
1944 basic_prep = true;
1945
1946 return did_something;
1947 }
1948
1949 static void replace_result_wire_name_in_function(AstNode *node, std::string &from, std::string &to)
1950 {
1951 for (auto &it : node->children)
1952 replace_result_wire_name_in_function(it, from, to);
1953 if (node->str == from)
1954 node->str = to;
1955 }
1956
1957 // annotate the names of all wires and other named objects in a generate block
1958 void AstNode::expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map)
1959 {
1960 if (!index_var.empty() && type == AST_IDENTIFIER && str == index_var) {
1961 current_scope[index_var]->children[0]->cloneInto(this);
1962 return;
1963 }
1964
1965 if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL) && name_map.count(str) > 0)
1966 str = name_map[str];
1967
1968 std::map<std::string, std::string> backup_name_map;
1969
1970 for (size_t i = 0; i < children.size(); i++) {
1971 AstNode *child = children[i];
1972 if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM ||
1973 child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL) {
1974 if (backup_name_map.size() == 0)
1975 backup_name_map = name_map;
1976 std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix;
1977 size_t pos = child->str.rfind('.');
1978 if (pos == std::string::npos)
1979 pos = child->str[0] == '\\' ? 1 : 0;
1980 else
1981 pos = pos + 1;
1982 new_name = child->str.substr(0, pos) + new_name + child->str.substr(pos);
1983 if (new_name[0] != '$' && new_name[0] != '\\')
1984 new_name = prefix[0] + new_name;
1985 name_map[child->str] = new_name;
1986 if (child->type == AST_FUNCTION)
1987 replace_result_wire_name_in_function(child, child->str, new_name);
1988 else
1989 child->str = new_name;
1990 current_scope[new_name] = child;
1991 }
1992 }
1993
1994 for (size_t i = 0; i < children.size(); i++) {
1995 AstNode *child = children[i];
1996 if (child->type != AST_FUNCTION && child->type != AST_TASK && child->type != AST_PREFIX)
1997 child->expand_genblock(index_var, prefix, name_map);
1998 }
1999
2000 if (backup_name_map.size() > 0)
2001 name_map.swap(backup_name_map);
2002 }
2003
2004 // rename stuff (used when tasks of functions are instanciated)
2005 void AstNode::replace_ids(const std::string &prefix, const std::map<std::string, std::string> &rules)
2006 {
2007 if (type == AST_BLOCK)
2008 {
2009 std::map<std::string, std::string> new_rules = rules;
2010 std::string new_prefix = prefix + str;
2011
2012 for (auto child : children)
2013 if (child->type == AST_WIRE) {
2014 new_rules[child->str] = new_prefix + child->str;
2015 child->str = new_prefix + child->str;
2016 }
2017
2018 for (auto child : children)
2019 if (child->type != AST_WIRE)
2020 child->replace_ids(new_prefix, new_rules);
2021 }
2022 else
2023 {
2024 if (type == AST_IDENTIFIER && rules.count(str) > 0)
2025 str = rules.at(str);
2026 for (auto child : children)
2027 child->replace_ids(prefix, rules);
2028 }
2029 }
2030
2031 // helper function for mem2reg_as_needed_pass1
2032 static void mark_memories_assign_lhs_complex(std::map<AstNode*, std::set<std::string>> &mem2reg_places,
2033 std::map<AstNode*, uint32_t> &mem2reg_candidates, AstNode *that)
2034 {
2035 for (auto &child : that->children)
2036 mark_memories_assign_lhs_complex(mem2reg_places, mem2reg_candidates, child);
2037
2038 if (that->type == AST_IDENTIFIER && that->id2ast && that->id2ast->type == AST_MEMORY) {
2039 AstNode *mem = that->id2ast;
2040 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_CMPLX_LHS))
2041 mem2reg_places[mem].insert(stringf("%s:%d", that->filename.c_str(), that->linenum));
2042 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CMPLX_LHS;
2043 }
2044 }
2045
2046 // find memories that should be replaced by registers
2047 void AstNode::mem2reg_as_needed_pass1(std::map<AstNode*, std::set<std::string>> &mem2reg_places,
2048 std::map<AstNode*, uint32_t> &mem2reg_candidates, std::map<AstNode*, uint32_t> &proc_flags, uint32_t &flags)
2049 {
2050 uint32_t children_flags = 0;
2051 int ignore_children_counter = 0;
2052
2053 if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ)
2054 {
2055 // mark all memories that are used in a complex expression on the left side of an assignment
2056 for (auto &lhs_child : children[0]->children)
2057 mark_memories_assign_lhs_complex(mem2reg_places, mem2reg_candidates, lhs_child);
2058
2059 if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY)
2060 {
2061 AstNode *mem = children[0]->id2ast;
2062
2063 // activate mem2reg if this is assigned in an async proc
2064 if (flags & AstNode::MEM2REG_FL_ASYNC) {
2065 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ASYNC))
2066 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
2067 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ASYNC;
2068 }
2069
2070 // remember if this is assigned blocking (=)
2071 if (type == AST_ASSIGN_EQ) {
2072 if (!(proc_flags[mem] & AstNode::MEM2REG_FL_EQ1))
2073 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
2074 proc_flags[mem] |= AstNode::MEM2REG_FL_EQ1;
2075 }
2076
2077 // remember where this is
2078 if (flags & MEM2REG_FL_INIT) {
2079 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_INIT))
2080 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
2081 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_INIT;
2082 } else {
2083 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ELSE))
2084 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
2085 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ELSE;
2086 }
2087 }
2088
2089 ignore_children_counter = 1;
2090 }
2091
2092 if (type == AST_IDENTIFIER && id2ast && id2ast->type == AST_MEMORY)
2093 {
2094 AstNode *mem = id2ast;
2095
2096 // flag if used after blocking assignment (in same proc)
2097 if ((proc_flags[mem] & AstNode::MEM2REG_FL_EQ1) && !(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_EQ2)) {
2098 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
2099 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_EQ2;
2100 }
2101 }
2102
2103 // also activate if requested, either by using mem2reg attribute or by declaring array as 'wire' instead of 'reg'
2104 if (type == AST_MEMORY && (get_bool_attribute("\\mem2reg") || (flags & AstNode::MEM2REG_FL_ALL) || !is_reg))
2105 mem2reg_candidates[this] |= AstNode::MEM2REG_FL_FORCED;
2106
2107 if (type == AST_MODULE && get_bool_attribute("\\mem2reg"))
2108 children_flags |= AstNode::MEM2REG_FL_ALL;
2109
2110 std::map<AstNode*, uint32_t> *proc_flags_p = NULL;
2111
2112 if (type == AST_ALWAYS) {
2113 int count_edge_events = 0;
2114 for (auto child : children)
2115 if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE)
2116 count_edge_events++;
2117 if (count_edge_events != 1)
2118 children_flags |= AstNode::MEM2REG_FL_ASYNC;
2119 proc_flags_p = new std::map<AstNode*, uint32_t>;
2120 }
2121
2122 if (type == AST_INITIAL) {
2123 children_flags |= AstNode::MEM2REG_FL_INIT;
2124 proc_flags_p = new std::map<AstNode*, uint32_t>;
2125 }
2126
2127 uint32_t backup_flags = flags;
2128 flags |= children_flags;
2129 log_assert((flags & ~0x000000ff) == 0);
2130
2131 for (auto child : children)
2132 if (ignore_children_counter > 0)
2133 ignore_children_counter--;
2134 else if (proc_flags_p)
2135 child->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, *proc_flags_p, flags);
2136 else
2137 child->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, proc_flags, flags);
2138
2139 flags &= ~children_flags | backup_flags;
2140
2141 if (proc_flags_p) {
2142 for (auto it : *proc_flags_p)
2143 log_assert((it.second & ~0xff000000) == 0);
2144 delete proc_flags_p;
2145 }
2146 }
2147
2148 // actually replace memories with registers
2149 void AstNode::mem2reg_as_needed_pass2(std::set<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block)
2150 {
2151 if (type == AST_BLOCK)
2152 block = this;
2153
2154 if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && block != NULL && children[0]->id2ast &&
2155 mem2reg_set.count(children[0]->id2ast) > 0 && children[0]->children[0]->children[0]->type != AST_CONSTANT)
2156 {
2157 std::stringstream sstr;
2158 sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++);
2159 std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
2160
2161 int mem_width, mem_size, addr_bits;
2162 children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
2163
2164 AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
2165 wire_addr->str = id_addr;
2166 wire_addr->is_reg = true;
2167 wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
2168 mod->children.push_back(wire_addr);
2169 while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
2170
2171 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
2172 wire_data->str = id_data;
2173 wire_data->is_reg = true;
2174 wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
2175 mod->children.push_back(wire_data);
2176 while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
2177
2178 log_assert(block != NULL);
2179 size_t assign_idx = 0;
2180 while (assign_idx < block->children.size() && block->children[assign_idx] != this)
2181 assign_idx++;
2182 log_assert(assign_idx < block->children.size());
2183
2184 AstNode *assign_addr = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());
2185 assign_addr->children[0]->str = id_addr;
2186 block->children.insert(block->children.begin()+assign_idx+1, assign_addr);
2187
2188 AstNode *case_node = new AstNode(AST_CASE, new AstNode(AST_IDENTIFIER));
2189 case_node->children[0]->str = id_addr;
2190 for (int i = 0; i < mem_size; i++) {
2191 if (children[0]->children[0]->children[0]->type == AST_CONSTANT && int(children[0]->children[0]->children[0]->integer) != i)
2192 continue;
2193 AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK));
2194 AstNode *assign_reg = new AstNode(type, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER));
2195 if (children[0]->children.size() == 2)
2196 assign_reg->children[0]->children.push_back(children[0]->children[1]->clone());
2197 assign_reg->children[0]->str = stringf("%s[%d]", children[0]->str.c_str(), i);
2198 assign_reg->children[1]->str = id_data;
2199 cond_node->children[1]->children.push_back(assign_reg);
2200 case_node->children.push_back(cond_node);
2201 }
2202 block->children.insert(block->children.begin()+assign_idx+2, case_node);
2203
2204 children[0]->delete_children();
2205 children[0]->range_valid = false;
2206 children[0]->id2ast = NULL;
2207 children[0]->str = id_data;
2208 type = AST_ASSIGN_EQ;
2209 }
2210
2211 if (type == AST_IDENTIFIER && id2ast && mem2reg_set.count(id2ast) > 0)
2212 {
2213 AstNode *bit_part_sel = NULL;
2214 if (children.size() == 2)
2215 bit_part_sel = children[1]->clone();
2216
2217 if (children[0]->children[0]->type == AST_CONSTANT)
2218 {
2219 int id = children[0]->children[0]->integer;
2220 str = stringf("%s[%d]", str.c_str(), id);
2221
2222 delete_children();
2223 range_valid = false;
2224 id2ast = NULL;
2225 }
2226 else
2227 {
2228 std::stringstream sstr;
2229 sstr << "$mem2reg_rd$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++);
2230 std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
2231
2232 int mem_width, mem_size, addr_bits;
2233 id2ast->meminfo(mem_width, mem_size, addr_bits);
2234
2235 AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
2236 wire_addr->str = id_addr;
2237 wire_addr->is_reg = true;
2238 if (block)
2239 wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
2240 mod->children.push_back(wire_addr);
2241 while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
2242
2243 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
2244 wire_data->str = id_data;
2245 wire_data->is_reg = true;
2246 if (block)
2247 wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
2248 mod->children.push_back(wire_data);
2249 while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
2250
2251 AstNode *assign_addr = new AstNode(block ? AST_ASSIGN_EQ : AST_ASSIGN, new AstNode(AST_IDENTIFIER), children[0]->children[0]->clone());
2252 assign_addr->children[0]->str = id_addr;
2253
2254 AstNode *case_node = new AstNode(AST_CASE, new AstNode(AST_IDENTIFIER));
2255 case_node->children[0]->str = id_addr;
2256
2257 for (int i = 0; i < mem_size; i++) {
2258 if (children[0]->children[0]->type == AST_CONSTANT && int(children[0]->children[0]->integer) != i)
2259 continue;
2260 AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK));
2261 AstNode *assign_reg = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER));
2262 assign_reg->children[0]->str = id_data;
2263 assign_reg->children[1]->str = stringf("%s[%d]", str.c_str(), i);
2264 cond_node->children[1]->children.push_back(assign_reg);
2265 case_node->children.push_back(cond_node);
2266 }
2267
2268 std::vector<RTLIL::State> x_bits;
2269 for (int i = 0; i < mem_width; i++)
2270 x_bits.push_back(RTLIL::State::Sx);
2271
2272 AstNode *cond_node = new AstNode(AST_COND, new AstNode(AST_DEFAULT), new AstNode(AST_BLOCK));
2273 AstNode *assign_reg = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), AstNode::mkconst_bits(x_bits, false));
2274 assign_reg->children[0]->str = id_data;
2275 cond_node->children[1]->children.push_back(assign_reg);
2276 case_node->children.push_back(cond_node);
2277
2278 if (block)
2279 {
2280 size_t assign_idx = 0;
2281 while (assign_idx < block->children.size() && !block->children[assign_idx]->contains(this))
2282 assign_idx++;
2283 log_assert(assign_idx < block->children.size());
2284 block->children.insert(block->children.begin()+assign_idx, case_node);
2285 block->children.insert(block->children.begin()+assign_idx, assign_addr);
2286 }
2287 else
2288 {
2289 AstNode *proc = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
2290 proc->children[0]->children.push_back(case_node);
2291 mod->children.push_back(proc);
2292 mod->children.push_back(assign_addr);
2293 }
2294
2295 delete_children();
2296 range_valid = false;
2297 id2ast = NULL;
2298 str = id_data;
2299 }
2300
2301 if (bit_part_sel)
2302 children.push_back(bit_part_sel);
2303 }
2304
2305 log_assert(id2ast == NULL || mem2reg_set.count(id2ast) == 0);
2306
2307 auto children_list = children;
2308 for (size_t i = 0; i < children_list.size(); i++)
2309 children_list[i]->mem2reg_as_needed_pass2(mem2reg_set, mod, block);
2310 }
2311
2312 // calulate memory dimensions
2313 void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits)
2314 {
2315 log_assert(type == AST_MEMORY);
2316
2317 mem_width = children[0]->range_left - children[0]->range_right + 1;
2318 mem_size = children[1]->range_left - children[1]->range_right;
2319
2320 if (mem_size < 0)
2321 mem_size *= -1;
2322 mem_size += std::min(children[1]->range_left, children[1]->range_right) + 1;
2323
2324 addr_bits = 1;
2325 while ((1 << addr_bits) < mem_size)
2326 addr_bits++;
2327 }
2328
2329 bool AstNode::has_const_only_constructs(bool &recommend_const_eval)
2330 {
2331 if (type == AST_FOR)
2332 recommend_const_eval = true;
2333 if (type == AST_WHILE || type == AST_REPEAT)
2334 return true;
2335 if (type == AST_FCALL && current_scope.count(str))
2336 if (current_scope[str]->has_const_only_constructs(recommend_const_eval))
2337 return true;
2338 for (auto child : children)
2339 if (child->AstNode::has_const_only_constructs(recommend_const_eval))
2340 return true;
2341 return false;
2342 }
2343
2344 // helper function for AstNode::eval_const_function()
2345 void AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &variables, AstNode *fcall)
2346 {
2347 if (type == AST_IDENTIFIER && variables.count(str)) {
2348 int offset = variables.at(str).offset, width = variables.at(str).val.bits.size();
2349 if (!children.empty()) {
2350 if (children.size() != 1 || children.at(0)->type != AST_RANGE)
2351 log_error("Memory access in constant function is not supported in %s:%d (called from %s:%d).\n",
2352 filename.c_str(), linenum, fcall->filename.c_str(), fcall->linenum);
2353 children.at(0)->replace_variables(variables, fcall);
2354 while (simplify(true, false, false, 1, -1, false, true)) { }
2355 if (!children.at(0)->range_valid)
2356 log_error("Non-constant range in %s:%d (called from %s:%d).\n",
2357 filename.c_str(), linenum, fcall->filename.c_str(), fcall->linenum);
2358 offset = std::min(children.at(0)->range_left, children.at(0)->range_right);
2359 width = std::min(std::abs(children.at(0)->range_left - children.at(0)->range_right) + 1, width);
2360 }
2361 offset -= variables.at(str).offset;
2362 std::vector<RTLIL::State> &var_bits = variables.at(str).val.bits;
2363 std::vector<RTLIL::State> new_bits(var_bits.begin() + offset, var_bits.begin() + offset + width);
2364 AstNode *newNode = mkconst_bits(new_bits, variables.at(str).is_signed);
2365 newNode->cloneInto(this);
2366 delete newNode;
2367 return;
2368 }
2369
2370 for (auto &child : children)
2371 child->replace_variables(variables, fcall);
2372 }
2373
2374 // evaluate functions with all-const arguments
2375 AstNode *AstNode::eval_const_function(AstNode *fcall)
2376 {
2377 std::map<std::string, AstNode*> backup_scope;
2378 std::map<std::string, AstNode::varinfo_t> variables;
2379 bool delete_temp_block = false;
2380 AstNode *block = NULL;
2381
2382 size_t argidx = 0;
2383 for (auto child : children)
2384 {
2385 if (child->type == AST_BLOCK)
2386 {
2387 log_assert(block == NULL);
2388 block = child;
2389 continue;
2390 }
2391
2392 if (child->type == AST_WIRE)
2393 {
2394 while (child->simplify(true, false, false, 1, -1, false, true)) { }
2395 if (!child->range_valid)
2396 log_error("Can't determine size of variable %s in %s:%d (called from %s:%d).\n",
2397 child->str.c_str(), child->filename.c_str(), child->linenum, fcall->filename.c_str(), fcall->linenum);
2398 variables[child->str].val = RTLIL::Const(RTLIL::State::Sx, abs(child->range_left - child->range_right)+1);
2399 variables[child->str].offset = std::min(child->range_left, child->range_right);
2400 variables[child->str].is_signed = child->is_signed;
2401 if (child->is_input && argidx < fcall->children.size())
2402 variables[child->str].val = fcall->children.at(argidx++)->bitsAsConst(variables[child->str].val.bits.size());
2403 backup_scope[child->str] = current_scope[child->str];
2404 current_scope[child->str] = child;
2405 continue;
2406 }
2407
2408 log_assert(block == NULL);
2409 delete_temp_block = true;
2410 block = new AstNode(AST_BLOCK);
2411 block->children.push_back(child->clone());
2412 }
2413
2414 log_assert(block != NULL);
2415 log_assert(variables.count(str));
2416
2417 while (!block->children.empty())
2418 {
2419 AstNode *stmt = block->children.front();
2420
2421 #if 0
2422 log("-----------------------------------\n");
2423 for (auto &it : variables)
2424 log("%20s %40s\n", it.first.c_str(), log_signal(it.second.val));
2425 stmt->dumpAst(NULL, "stmt> ");
2426 #endif
2427
2428 if (stmt->type == AST_ASSIGN_EQ)
2429 {
2430 stmt->children.at(1)->replace_variables(variables, fcall);
2431 while (stmt->simplify(true, false, false, 1, -1, false, true)) { }
2432
2433 if (stmt->type != AST_ASSIGN_EQ)
2434 continue;
2435
2436 if (stmt->children.at(1)->type != AST_CONSTANT)
2437 log_error("Non-constant expression in constant function at %s:%d (called from %s:%d). X\n",
2438 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
2439
2440 if (stmt->children.at(0)->type != AST_IDENTIFIER)
2441 log_error("Unsupported composite left hand side in constant function at %s:%d (called from %s:%d).\n",
2442 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
2443
2444 if (!variables.count(stmt->children.at(0)->str))
2445 log_error("Assignment to non-local variable in constant function at %s:%d (called from %s:%d).\n",
2446 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
2447
2448 if (stmt->children.at(0)->children.empty()) {
2449 variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size());
2450 } else {
2451 AstNode *range = stmt->children.at(0)->children.at(0);
2452 if (!range->range_valid)
2453 log_error("Non-constant range in %s:%d (called from %s:%d).\n",
2454 range->filename.c_str(), range->linenum, fcall->filename.c_str(), fcall->linenum);
2455 int offset = std::min(range->range_left, range->range_right);
2456 int width = std::abs(range->range_left - range->range_right) + 1;
2457 varinfo_t &v = variables[stmt->children.at(0)->str];
2458 RTLIL::Const r = stmt->children.at(1)->bitsAsConst(v.val.bits.size());
2459 for (int i = 0; i < width; i++)
2460 v.val.bits.at(i+offset-v.offset) = r.bits.at(i);
2461 }
2462
2463 delete block->children.front();
2464 block->children.erase(block->children.begin());
2465 continue;
2466 }
2467
2468 if (stmt->type == AST_FOR)
2469 {
2470 block->children.insert(block->children.begin(), stmt->children.at(0));
2471 stmt->children.at(3)->children.push_back(stmt->children.at(2));
2472 stmt->children.erase(stmt->children.begin() + 2);
2473 stmt->children.erase(stmt->children.begin());
2474 stmt->type = AST_WHILE;
2475 continue;
2476 }
2477
2478 if (stmt->type == AST_WHILE)
2479 {
2480 AstNode *cond = stmt->children.at(0)->clone();
2481 cond->replace_variables(variables, fcall);
2482 while (cond->simplify(true, false, false, 1, -1, false, true)) { }
2483
2484 if (cond->type != AST_CONSTANT)
2485 log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n",
2486 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
2487
2488 if (cond->asBool()) {
2489 block->children.insert(block->children.begin(), stmt->children.at(1)->clone());
2490 } else {
2491 delete block->children.front();
2492 block->children.erase(block->children.begin());
2493 }
2494
2495 delete cond;
2496 continue;
2497 }
2498
2499 if (stmt->type == AST_REPEAT)
2500 {
2501 AstNode *num = stmt->children.at(0)->clone();
2502 num->replace_variables(variables, fcall);
2503 while (num->simplify(true, false, false, 1, -1, false, true)) { }
2504
2505 if (num->type != AST_CONSTANT)
2506 log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n",
2507 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
2508
2509 block->children.erase(block->children.begin());
2510 for (int i = 0; i < num->bitsAsConst().as_int(); i++)
2511 block->children.insert(block->children.begin(), stmt->children.at(1)->clone());
2512
2513 delete stmt;
2514 delete num;
2515 continue;
2516 }
2517
2518 if (stmt->type == AST_CASE)
2519 {
2520 AstNode *expr = stmt->children.at(0)->clone();
2521 expr->replace_variables(variables, fcall);
2522 while (expr->simplify(true, false, false, 1, -1, false, true)) { }
2523
2524 AstNode *sel_case = NULL;
2525 for (size_t i = 1; i < stmt->children.size(); i++)
2526 {
2527 bool found_match = false;
2528 log_assert(stmt->children.at(i)->type == AST_COND);
2529
2530 if (stmt->children.at(i)->children.front()->type == AST_DEFAULT) {
2531 sel_case = stmt->children.at(i)->children.back();
2532 continue;
2533 }
2534
2535 for (size_t j = 0; j+1 < stmt->children.at(i)->children.size() && !found_match; j++)
2536 {
2537 AstNode *cond = stmt->children.at(i)->children.at(j)->clone();
2538 cond->replace_variables(variables, fcall);
2539
2540 cond = new AstNode(AST_EQ, expr->clone(), cond);
2541 while (cond->simplify(true, false, false, 1, -1, false, true)) { }
2542
2543 if (cond->type != AST_CONSTANT)
2544 log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n",
2545 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
2546
2547 found_match = cond->asBool();
2548 delete cond;
2549 }
2550
2551 if (found_match) {
2552 sel_case = stmt->children.at(i)->children.back();
2553 break;
2554 }
2555 }
2556
2557 block->children.erase(block->children.begin());
2558 if (sel_case)
2559 block->children.insert(block->children.begin(), sel_case->clone());
2560 delete stmt;
2561 delete expr;
2562 continue;
2563 }
2564
2565 if (stmt->type == AST_BLOCK)
2566 {
2567 block->children.erase(block->children.begin());
2568 block->children.insert(block->children.begin(), stmt->children.begin(), stmt->children.end());
2569 stmt->children.clear();
2570 delete stmt;
2571 continue;
2572 }
2573
2574 log_error("Unsupported language construct in constant function at %s:%d (called from %s:%d).\n",
2575 stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum);
2576 log_abort();
2577 }
2578
2579 if (delete_temp_block)
2580 delete block;
2581
2582 for (auto &it : backup_scope)
2583 if (it.second == NULL)
2584 current_scope.erase(it.first);
2585 else
2586 current_scope[it.first] = it.second;
2587
2588 return AstNode::mkconst_bits(variables.at(str).val.bits, variables.at(str).is_signed);
2589 }
2590
2591 YOSYS_NAMESPACE_END
2592