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