Added $assert cell
[yosys.git] / frontends / ast / simplify.cc
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * ---
19 *
20 * This is the AST frontend library.
21 *
22 * The AST frontend library is not a frontend on it's own but provides a
23 * generic abstract syntax tree (AST) abstraction for HDL code and can be
24 * used by HDL frontends. See "ast.h" for an overview of the API and the
25 * Verilog frontend for an usage example.
26 *
27 */
28
29 #include "kernel/log.h"
30 #include "libs/sha1/sha1.h"
31 #include "ast.h"
32
33 #include <sstream>
34 #include <stdarg.h>
35 #include <assert.h>
36
37 using namespace AST;
38 using namespace AST_INTERNAL;
39
40 // convert the AST into a simpler AST that has all parameters subsitited by their
41 // values, unrolled for-loops, expanded generate blocks, etc. when this function
42 // is done with an AST it can be converted into RTLIL using genRTLIL().
43 //
44 // this function also does all name resolving and sets the id2ast member of all
45 // nodes that link to a different node using names and lexical scoping.
46 bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint)
47 {
48 AstNode *newNode = NULL;
49 bool did_something = false;
50
51 if (stage == 0)
52 {
53 assert(type == AST_MODULE);
54
55 while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint)) { }
56
57 if (!flag_nomem2reg && !get_bool_attribute("\\nomem2reg"))
58 {
59 std::map<AstNode*, std::set<std::string>> mem2reg_places;
60 std::map<AstNode*, uint32_t> mem2reg_candidates, dummy_proc_flags;
61 uint32_t flags = flag_mem2reg ? AstNode::MEM2REG_FL_ALL : 0;
62 mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, dummy_proc_flags, flags);
63
64 std::set<AstNode*> mem2reg_set;
65 for (auto &it : mem2reg_candidates)
66 {
67 AstNode *mem = it.first;
68 uint32_t memflags = it.second;
69 assert((memflags & ~0x00ffff00) == 0);
70
71 if (mem->get_bool_attribute("\\nomem2reg"))
72 continue;
73
74 if (memflags & AstNode::MEM2REG_FL_FORCED)
75 goto silent_activate;
76
77 if (memflags & AstNode::MEM2REG_FL_EQ2)
78 goto verbose_activate;
79
80 if (memflags & AstNode::MEM2REG_FL_SET_ASYNC)
81 goto verbose_activate;
82
83 if ((memflags & AstNode::MEM2REG_FL_SET_INIT) && (memflags & AstNode::MEM2REG_FL_SET_ELSE))
84 goto verbose_activate;
85
86 // log("Note: Not replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
87 continue;
88
89 verbose_activate:
90 if (mem2reg_set.count(mem) == 0) {
91 log("Warning: Replacing memory %s with list of registers.", mem->str.c_str());
92 bool first_element = true;
93 for (auto &place : mem2reg_places[it.first]) {
94 log("%s%s", first_element ? " See " : ", ", place.c_str());
95 first_element = false;
96 }
97 log("\n");
98 }
99
100 silent_activate:
101 // log("Note: Replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
102 mem2reg_set.insert(mem);
103 }
104
105 for (auto node : mem2reg_set)
106 {
107 int mem_width, mem_size, addr_bits;
108 node->meminfo(mem_width, mem_size, addr_bits);
109
110 for (int i = 0; i < mem_size; i++) {
111 AstNode *reg = new AstNode(AST_WIRE, new AstNode(AST_RANGE,
112 mkconst_int(mem_width-1, true), mkconst_int(0, true)));
113 reg->str = stringf("%s[%d]", node->str.c_str(), i);
114 reg->is_reg = true;
115 reg->is_signed = node->is_signed;
116 children.push_back(reg);
117 while (reg->simplify(true, false, false, 1, -1, false)) { }
118 }
119 }
120
121 mem2reg_as_needed_pass2(mem2reg_set, this, NULL);
122
123 for (size_t i = 0; i < children.size(); i++) {
124 if (mem2reg_set.count(children[i]) > 0) {
125 delete children[i];
126 children.erase(children.begin() + (i--));
127 }
128 }
129 }
130
131 while (simplify(const_fold, at_zero, in_lvalue, 2, width_hint, sign_hint)) { }
132 return false;
133 }
134
135 current_filename = filename;
136 set_line_num(linenum);
137
138 // we do not look inside a task or function
139 // (but as soon as a task of function is instanciated we process the generated AST as usual)
140 if (type == AST_FUNCTION || type == AST_TASK)
141 return false;
142
143 // deactivate all calls non-synthesis system taks
144 if ((type == AST_FCALL || type == AST_TCALL) && (str == "$display" || str == "$stop" || str == "$finish")) {
145 delete_children();
146 str = std::string();
147 }
148
149 // activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
150 if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX)
151 const_fold = true;
152 if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM))
153 const_fold = true;
154
155 std::map<std::string, AstNode*> backup_scope;
156
157 // create name resolution entries for all objects with names
158 // also merge multiple declarations for the same wire (e.g. "output foobar; reg foobar;")
159 if (type == AST_MODULE) {
160 current_scope.clear();
161 std::map<std::string, AstNode*> this_wire_scope;
162 for (size_t i = 0; i < children.size(); i++) {
163 AstNode *node = children[i];
164 if (node->type == AST_WIRE) {
165 if (this_wire_scope.count(node->str) > 0) {
166 AstNode *first_node = this_wire_scope[node->str];
167 if (!node->is_input && !node->is_output && node->is_reg && node->children.size() == 0)
168 goto wires_are_compatible;
169 if (first_node->children.size() != node->children.size())
170 goto wires_are_incompatible;
171 for (size_t j = 0; j < node->children.size(); j++) {
172 AstNode *n1 = first_node->children[j], *n2 = node->children[j];
173 if (n1->type == AST_RANGE && n2->type == AST_RANGE && n1->range_valid && n2->range_valid) {
174 if (n1->range_left != n2->range_left)
175 goto wires_are_incompatible;
176 if (n1->range_right != n2->range_right)
177 goto wires_are_incompatible;
178 } else if (*n1 != *n2)
179 goto wires_are_incompatible;
180 }
181 if (first_node->range_left != node->range_left)
182 goto wires_are_incompatible;
183 if (first_node->range_right != node->range_right)
184 goto wires_are_incompatible;
185 if (first_node->port_id == 0 && (node->is_input || node->is_output))
186 goto wires_are_incompatible;
187 wires_are_compatible:
188 if (node->is_input)
189 first_node->is_input = true;
190 if (node->is_output)
191 first_node->is_output = true;
192 if (node->is_reg)
193 first_node->is_reg = true;
194 if (node->is_signed)
195 first_node->is_signed = true;
196 for (auto &it : node->attributes) {
197 if (first_node->attributes.count(it.first) > 0)
198 delete first_node->attributes[it.first];
199 first_node->attributes[it.first] = it.second->clone();
200 }
201 children.erase(children.begin()+(i--));
202 did_something = true;
203 delete node;
204 continue;
205 }
206 this_wire_scope[node->str] = node;
207 }
208 wires_are_incompatible:
209 if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
210 node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_CELL) {
211 backup_scope[node->str] = current_scope[node->str];
212 current_scope[node->str] = node;
213 }
214 }
215 for (size_t i = 0; i < children.size(); i++) {
216 AstNode *node = children[i];
217 if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE)
218 while (node->simplify(true, false, false, 1, -1, false)) { }
219 }
220 }
221
222 auto backup_current_block = current_block;
223 auto backup_current_block_child = current_block_child;
224 auto backup_current_top_block = current_top_block;
225
226 int backup_width_hint = width_hint;
227 bool backup_sign_hint = sign_hint;
228
229 bool detect_width_simple = false;
230 bool child_0_is_self_determined = false;
231 bool child_1_is_self_determined = false;
232 bool children_are_self_determined = false;
233 bool reset_width_after_children = false;
234
235 switch (type)
236 {
237 case AST_ASSIGN_EQ:
238 case AST_ASSIGN_LE:
239 case AST_ASSIGN:
240 while (children[0]->simplify(false, false, true, stage, -1, false) == true) { }
241 while (children[1]->simplify(false, false, false, stage, -1, false) == true) { }
242 children[0]->detectSignWidth(backup_width_hint, backup_sign_hint);
243 children[1]->detectSignWidth(width_hint, sign_hint);
244 width_hint = std::max(width_hint, backup_width_hint);
245 child_0_is_self_determined = true;
246 break;
247
248 case AST_PARAMETER:
249 case AST_LOCALPARAM:
250 while (children[0]->simplify(false, false, false, stage, -1, false) == true) { }
251 children[0]->detectSignWidth(width_hint, sign_hint);
252 if (children.size() > 1) {
253 assert(children[1]->type == AST_RANGE);
254 while (children[1]->simplify(false, false, false, stage, -1, false) == true) { }
255 if (!children[1]->range_valid)
256 log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum);
257 width_hint = std::max(width_hint, children[1]->range_left - children[1]->range_right + 1);
258 }
259 break;
260
261 case AST_TO_SIGNED:
262 case AST_TO_UNSIGNED:
263 case AST_CONCAT:
264 case AST_REPLICATE:
265 case AST_REDUCE_AND:
266 case AST_REDUCE_OR:
267 case AST_REDUCE_XOR:
268 case AST_REDUCE_XNOR:
269 case AST_REDUCE_BOOL:
270 detect_width_simple = true;
271 children_are_self_determined = true;
272 break;
273
274 case AST_NEG:
275 case AST_BIT_NOT:
276 case AST_POS:
277 case AST_BIT_AND:
278 case AST_BIT_OR:
279 case AST_BIT_XOR:
280 case AST_BIT_XNOR:
281 case AST_ADD:
282 case AST_SUB:
283 case AST_MUL:
284 case AST_DIV:
285 case AST_MOD:
286 detect_width_simple = true;
287 break;
288
289 case AST_SHIFT_LEFT:
290 case AST_SHIFT_RIGHT:
291 case AST_SHIFT_SLEFT:
292 case AST_SHIFT_SRIGHT:
293 case AST_POW:
294 detect_width_simple = true;
295 child_1_is_self_determined = true;
296 break;
297
298 case AST_LT:
299 case AST_LE:
300 case AST_EQ:
301 case AST_NE:
302 case AST_EQX:
303 case AST_NEX:
304 case AST_GE:
305 case AST_GT:
306 width_hint = -1;
307 sign_hint = true;
308 for (auto child : children) {
309 while (child->simplify(false, false, in_lvalue, stage, -1, false) == true) { }
310 child->detectSignWidthWorker(width_hint, sign_hint);
311 }
312 reset_width_after_children = true;
313 break;
314
315 case AST_LOGIC_AND:
316 case AST_LOGIC_OR:
317 case AST_LOGIC_NOT:
318 detect_width_simple = true;
319 children_are_self_determined = true;
320 break;
321
322 case AST_TERNARY:
323 detect_width_simple = true;
324 child_0_is_self_determined = true;
325 break;
326
327 case AST_MEMRD:
328 detect_width_simple = true;
329 children_are_self_determined = true;
330 break;
331
332 default:
333 width_hint = -1;
334 sign_hint = false;
335 }
336
337 if (detect_width_simple && width_hint < 0) {
338 for (auto child : children)
339 while (child->simplify(false, false, in_lvalue, stage, -1, false) == true) { }
340 if (type == AST_REPLICATE)
341 while (children[0]->simplify(true, false, in_lvalue, stage, -1, false) == true) { }
342 detectSignWidth(width_hint, sign_hint);
343 }
344
345 // simplify all children first
346 // (iterate by index as e.g. auto wires can add new children in the process)
347 for (size_t i = 0; i < children.size(); i++) {
348 bool did_something_here = true;
349 if ((type == AST_GENFOR || type == AST_FOR) && i >= 3)
350 break;
351 if ((type == AST_GENIF || type == AST_GENCASE) && i >= 1)
352 break;
353 if (type == AST_GENBLOCK)
354 break;
355 if (type == AST_BLOCK && !str.empty())
356 break;
357 if (type == AST_PREFIX && i >= 1)
358 break;
359 while (did_something_here && i < children.size()) {
360 bool const_fold_here = const_fold, in_lvalue_here = in_lvalue;
361 int width_hint_here = width_hint;
362 bool sign_hint_here = sign_hint;
363 if (i == 0 && type == AST_REPLICATE)
364 const_fold_here = true;
365 if (type == AST_PARAMETER || type == AST_LOCALPARAM)
366 const_fold_here = true;
367 if (i == 0 && (type == AST_ASSIGN || type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE))
368 in_lvalue_here = true;
369 if (type == AST_BLOCK) {
370 current_block = this;
371 current_block_child = children[i];
372 }
373 if ((type == AST_ALWAYS || type == AST_INITIAL) && children[i]->type == AST_BLOCK)
374 current_top_block = children[i];
375 if (i == 0 && child_0_is_self_determined)
376 width_hint_here = -1, sign_hint_here = false;
377 if (i == 1 && child_1_is_self_determined)
378 width_hint_here = -1, sign_hint_here = false;
379 if (children_are_self_determined)
380 width_hint_here = -1, sign_hint_here = false;
381 did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here);
382 if (did_something_here)
383 did_something = true;
384 }
385 }
386 for (auto &attr : attributes) {
387 while (attr.second->simplify(true, false, false, stage, -1, false)) { }
388 }
389
390 if (reset_width_after_children) {
391 width_hint = backup_width_hint;
392 sign_hint = backup_sign_hint;
393 if (width_hint < 0)
394 detectSignWidth(width_hint, sign_hint);
395 }
396
397 current_block = backup_current_block;
398 current_block_child = backup_current_block_child;
399 current_top_block = backup_current_top_block;
400
401 for (auto it = backup_scope.begin(); it != backup_scope.end(); it++) {
402 if (it->second == NULL)
403 current_scope.erase(it->first);
404 else
405 current_scope[it->first] = it->second;
406 }
407
408 current_filename = filename;
409 set_line_num(linenum);
410
411 if (type == AST_MODULE)
412 current_scope.clear();
413
414 // convert defparam nodes to cell parameters
415 if (type == AST_DEFPARAM && !str.empty()) {
416 size_t pos = str.rfind('.');
417 if (pos == std::string::npos)
418 log_error("Defparam `%s' does not contain a dot (module/parameter seperator) at %s:%d!\n",
419 RTLIL::id2cstr(str.c_str()), filename.c_str(), linenum);
420 std::string modname = str.substr(0, pos), paraname = "\\" + str.substr(pos+1);
421 if (current_scope.count(modname) == 0 || current_scope.at(modname)->type != AST_CELL)
422 log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::id2cstr(modname), RTLIL::id2cstr(paraname), filename.c_str(), linenum);
423 AstNode *cell = current_scope.at(modname), *paraset = clone();
424 cell->children.insert(cell->children.begin() + 1, paraset);
425 paraset->type = AST_PARASET;
426 paraset->str = paraname;
427 str.clear();
428 }
429
430 // resolve constant prefixes
431 if (type == AST_PREFIX) {
432 if (children[0]->type != AST_CONSTANT) {
433 // dumpAst(NULL, "> ");
434 log_error("Index in generate block prefix syntax at %s:%d is not constant!\n", filename.c_str(), linenum);
435 }
436 assert(children[1]->type == AST_IDENTIFIER);
437 newNode = children[1]->clone();
438 const char *second_part = children[1]->str.c_str();
439 if (second_part[0] == '\\')
440 second_part++;
441 newNode->str = stringf("%s[%d].%s", str.c_str(), children[0]->integer, second_part);
442 goto apply_newNode;
443 }
444
445 // annotate constant ranges
446 if (type == AST_RANGE) {
447 bool old_range_valid = range_valid;
448 range_valid = false;
449 range_left = -1;
450 range_right = 0;
451 assert(children.size() >= 1);
452 if (children[0]->type == AST_CONSTANT) {
453 range_valid = true;
454 range_left = children[0]->integer;
455 if (children.size() == 1)
456 range_right = range_left;
457 }
458 if (children.size() >= 2) {
459 if (children[1]->type == AST_CONSTANT)
460 range_right = children[1]->integer;
461 else
462 range_valid = false;
463 }
464 if (old_range_valid != range_valid)
465 did_something = true;
466 if (range_valid && range_left >= 0 && range_right > range_left) {
467 int tmp = range_right;
468 range_right = range_left;
469 range_left = tmp;
470 }
471 }
472
473 // annotate wires with their ranges
474 if (type == AST_WIRE) {
475 if (children.size() > 0) {
476 if (children[0]->range_valid) {
477 if (!range_valid)
478 did_something = true;
479 range_valid = true;
480 range_left = children[0]->range_left;
481 range_right = children[0]->range_right;
482 }
483 } else {
484 if (!range_valid)
485 did_something = true;
486 range_valid = true;
487 range_left = 0;
488 range_right = 0;
489 }
490 }
491
492 // trim/extend parameters
493 if ((type == AST_PARAMETER || type == AST_LOCALPARAM) && children[0]->type == AST_CONSTANT && children.size() > 1) {
494 if (!children[1]->range_valid)
495 log_error("Non-constant width range on parameter decl at %s:%d.\n", filename.c_str(), linenum);
496 int width = children[1]->range_left - children[1]->range_right + 1;
497 if (width != int(children[0]->bits.size())) {
498 RTLIL::SigSpec sig(children[0]->bits);
499 sig.extend_u0(width, children[0]->is_signed);
500 AstNode *old_child_0 = children[0];
501 children[0] = mkconst_bits(sig.as_const().bits, children[0]->is_signed);
502 delete old_child_0;
503 }
504 children[0]->is_signed = is_signed;
505 }
506
507 // annotate identifiers using scope resolution and create auto-wires as needed
508 if (type == AST_IDENTIFIER) {
509 if (current_scope.count(str) == 0) {
510 for (auto node : current_ast_mod->children) {
511 if ((node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
512 node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK) && str == node->str) {
513 current_scope[node->str] = node;
514 break;
515 }
516 }
517 }
518 if (current_scope.count(str) == 0) {
519 // log("Warning: Creating auto-wire `%s' in module `%s'.\n", str.c_str(), current_ast_mod->str.c_str());
520 AstNode *auto_wire = new AstNode(AST_AUTOWIRE);
521 auto_wire->str = str;
522 current_ast_mod->children.push_back(auto_wire);
523 current_scope[str] = auto_wire;
524 did_something = true;
525 }
526 id2ast = current_scope[str];
527 }
528
529 // split memory access with bit select to individual statements
530 if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE)
531 {
532 if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1 || in_lvalue)
533 log_error("Invalid bit-select on memory access at %s:%d!\n", filename.c_str(), linenum);
534
535 int mem_width, mem_size, addr_bits;
536 id2ast->meminfo(mem_width, mem_size, addr_bits);
537
538 std::stringstream sstr;
539 sstr << "$mem2bits$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++);
540 std::string wire_id = sstr.str();
541
542 AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
543 wire->str = wire_id;
544 if (current_block)
545 wire->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
546 current_ast_mod->children.push_back(wire);
547 while (wire->simplify(true, false, false, 1, -1, false)) { }
548
549 AstNode *data = clone();
550 delete data->children[1];
551 data->children.pop_back();
552
553 AstNode *assign = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), data);
554 assign->children[0]->str = wire_id;
555
556 if (current_block)
557 {
558 size_t assign_idx = 0;
559 while (assign_idx < current_block->children.size() && current_block->children[assign_idx] != current_block_child)
560 assign_idx++;
561 log_assert(assign_idx < current_block->children.size());
562 current_block->children.insert(current_block->children.begin()+assign_idx, assign);
563 wire->is_reg = true;
564 }
565 else
566 {
567 AstNode *proc = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
568 proc->children[0]->children.push_back(assign);
569 current_ast_mod->children.push_back(proc);
570 }
571
572 newNode = new AstNode(AST_IDENTIFIER, children[1]->clone());
573 newNode->str = wire_id;
574 newNode->id2ast = wire;
575 goto apply_newNode;
576 }
577
578 // unroll for loops and generate-for blocks
579 if ((type == AST_GENFOR || type == AST_FOR) && children.size() != 0)
580 {
581 AstNode *init_ast = children[0];
582 AstNode *while_ast = children[1];
583 AstNode *next_ast = children[2];
584 AstNode *body_ast = children[3];
585
586 while (body_ast->type == AST_GENBLOCK && body_ast->str.empty() &&
587 body_ast->children.size() == 1 && body_ast->children.at(0)->type == AST_GENBLOCK)
588 body_ast = body_ast->children.at(0);
589
590 if (init_ast->type != AST_ASSIGN_EQ)
591 log_error("Unsupported 1st expression of generate for-loop at %s:%d!\n", filename.c_str(), linenum);
592 if (next_ast->type != AST_ASSIGN_EQ)
593 log_error("Unsupported 3rd expression of generate for-loop at %s:%d!\n", filename.c_str(), linenum);
594
595 if (type == AST_GENFOR) {
596 if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_GENVAR)
597 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);
598 if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_GENVAR)
599 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);
600 } else {
601 if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != AST_WIRE)
602 log_error("Left hand side of 1st expression of generate for-loop at %s:%d is not a register!\n", filename.c_str(), linenum);
603 if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != AST_WIRE)
604 log_error("Left hand side of 3rd expression of generate for-loop at %s:%d is not a register!\n", filename.c_str(), linenum);
605 }
606
607 if (init_ast->children[0]->id2ast != next_ast->children[0]->id2ast)
608 log_error("Incompatible left-hand sides in 1st and 3rd expression of generate for-loop at %s:%d!\n", filename.c_str(), linenum);
609
610 // eval 1st expression
611 AstNode *varbuf = init_ast->children[1]->clone();
612 while (varbuf->simplify(true, false, false, stage, width_hint, sign_hint)) { }
613
614 if (varbuf->type != AST_CONSTANT)
615 log_error("Right hand side of 1st expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum);
616
617 varbuf = new AstNode(AST_LOCALPARAM, varbuf);
618 varbuf->str = init_ast->children[0]->str;
619
620 AstNode *backup_scope_varbuf = current_scope[varbuf->str];
621 current_scope[varbuf->str] = varbuf;
622
623 size_t current_block_idx = 0;
624 if (type == AST_FOR) {
625 while (current_block_idx < current_block->children.size() &&
626 current_block->children[current_block_idx] != current_block_child)
627 current_block_idx++;
628 }
629
630 while (1)
631 {
632 // eval 2nd expression
633 AstNode *buf = while_ast->clone();
634 while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { }
635
636 if (buf->type != AST_CONSTANT)
637 log_error("2nd expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum);
638
639 if (buf->integer == 0) {
640 delete buf;
641 break;
642 }
643 delete buf;
644
645 // expand body
646 int index = varbuf->children[0]->integer;
647 if (body_ast->type == AST_GENBLOCK)
648 buf = body_ast->clone();
649 else
650 buf = new AstNode(AST_GENBLOCK, body_ast->clone());
651 if (buf->str.empty()) {
652 std::stringstream sstr;
653 sstr << "$genblock$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++);
654 buf->str = sstr.str();
655 }
656 std::map<std::string, std::string> name_map;
657 std::stringstream sstr;
658 sstr << buf->str << "[" << index << "].";
659 buf->expand_genblock(varbuf->str, sstr.str(), name_map);
660
661 if (type == AST_GENFOR) {
662 for (size_t i = 0; i < buf->children.size(); i++) {
663 buf->children[i]->simplify(false, false, false, stage, -1, false);
664 current_ast_mod->children.push_back(buf->children[i]);
665 }
666 } else {
667 for (size_t i = 0; i < buf->children.size(); i++)
668 current_block->children.insert(current_block->children.begin() + current_block_idx++, buf->children[i]);
669 }
670 buf->children.clear();
671 delete buf;
672
673 // eval 3rd expression
674 buf = next_ast->children[1]->clone();
675 while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { }
676
677 if (buf->type != AST_CONSTANT)
678 log_error("Right hand side of 3rd expression of generate for-loop at %s:%d is not constant!\n", filename.c_str(), linenum);
679
680 delete varbuf->children[0];
681 varbuf->children[0] = buf;
682 }
683
684 current_scope[varbuf->str] = backup_scope_varbuf;
685 delete varbuf;
686 delete_children();
687 did_something = true;
688 }
689
690 // transform block with name
691 if (type == AST_BLOCK && !str.empty())
692 {
693 std::map<std::string, std::string> name_map;
694 expand_genblock(std::string(), str + ".", name_map);
695
696 std::vector<AstNode*> new_children;
697 for (size_t i = 0; i < children.size(); i++)
698 if (children[i]->type == AST_WIRE) {
699 children[i]->simplify(false, false, false, stage, -1, false);
700 current_ast_mod->children.push_back(children[i]);
701 } else
702 new_children.push_back(children[i]);
703
704 children.swap(new_children);
705 did_something = true;
706 str.clear();
707 }
708
709 // simplify unconditional generate block
710 if (type == AST_GENBLOCK && children.size() != 0)
711 {
712 if (!str.empty()) {
713 std::map<std::string, std::string> name_map;
714 expand_genblock(std::string(), str + ".", name_map);
715 }
716
717 for (size_t i = 0; i < children.size(); i++) {
718 children[i]->simplify(false, false, false, stage, -1, false);
719 current_ast_mod->children.push_back(children[i]);
720 }
721
722 children.clear();
723 did_something = true;
724 }
725
726 // simplify generate-if blocks
727 if (type == AST_GENIF && children.size() != 0)
728 {
729 AstNode *buf = children[0]->clone();
730 while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { }
731 if (buf->type != AST_CONSTANT) {
732 // for (auto f : log_files)
733 // dumpAst(f, "verilog-ast> ");
734 log_error("Condition for generate if at %s:%d is not constant!\n", filename.c_str(), linenum);
735 }
736 if (buf->asBool() != 0) {
737 delete buf;
738 buf = children[1]->clone();
739 } else {
740 delete buf;
741 buf = children.size() > 2 ? children[2]->clone() : NULL;
742 }
743
744 if (buf)
745 {
746 if (buf->type != AST_GENBLOCK)
747 buf = new AstNode(AST_GENBLOCK, buf);
748
749 if (!buf->str.empty()) {
750 std::map<std::string, std::string> name_map;
751 buf->expand_genblock(std::string(), buf->str + ".", name_map);
752 }
753
754 for (size_t i = 0; i < buf->children.size(); i++) {
755 buf->children[i]->simplify(false, false, false, stage, -1, false);
756 current_ast_mod->children.push_back(buf->children[i]);
757 }
758
759 buf->children.clear();
760 delete buf;
761 }
762
763 delete_children();
764 did_something = true;
765 }
766
767 // simplify generate-case blocks
768 if (type == AST_GENCASE && children.size() != 0)
769 {
770 AstNode *buf = children[0]->clone();
771 while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { }
772 if (buf->type != AST_CONSTANT) {
773 // for (auto f : log_files)
774 // dumpAst(f, "verilog-ast> ");
775 log_error("Condition for generate case at %s:%d is not constant!\n", filename.c_str(), linenum);
776 }
777
778 bool ref_signed = buf->is_signed;
779 RTLIL::Const ref_value = buf->bitsAsConst();
780 delete buf;
781
782 AstNode *selected_case = NULL;
783 for (size_t i = 1; i < children.size(); i++)
784 {
785 log_assert(children.at(i)->type == AST_COND);
786
787 AstNode *this_genblock = NULL;
788 for (auto child : children.at(i)->children) {
789 log_assert(this_genblock == NULL);
790 if (child->type == AST_GENBLOCK)
791 this_genblock = child;
792 }
793
794 for (auto child : children.at(i)->children)
795 {
796 if (child->type == AST_DEFAULT) {
797 if (selected_case == NULL)
798 selected_case = this_genblock;
799 continue;
800 }
801 if (child->type == AST_GENBLOCK)
802 continue;
803
804 buf = child->clone();
805 while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { }
806 if (buf->type != AST_CONSTANT) {
807 // for (auto f : log_files)
808 // dumpAst(f, "verilog-ast> ");
809 log_error("Expression in generate case at %s:%d is not constant!\n", filename.c_str(), linenum);
810 }
811
812 if (RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool()) {
813 selected_case = this_genblock;
814 i = children.size();
815 break;
816 }
817 }
818 }
819
820 if (selected_case != NULL)
821 {
822 log_assert(selected_case->type == AST_GENBLOCK);
823 buf = selected_case->clone();
824
825 if (!buf->str.empty()) {
826 std::map<std::string, std::string> name_map;
827 buf->expand_genblock(std::string(), buf->str + ".", name_map);
828 }
829
830 for (size_t i = 0; i < buf->children.size(); i++) {
831 buf->children[i]->simplify(false, false, false, stage, -1, false);
832 current_ast_mod->children.push_back(buf->children[i]);
833 }
834
835 buf->children.clear();
836 delete buf;
837 }
838
839 delete_children();
840 did_something = true;
841 }
842
843 // replace primitives with assignmens
844 if (type == AST_PRIMITIVE)
845 {
846 if (children.size() < 2)
847 log_error("Insufficient number of arguments for primitive `%s' at %s:%d!\n",
848 str.c_str(), filename.c_str(), linenum);
849
850 std::vector<AstNode*> children_list;
851 for (auto child : children) {
852 assert(child->type == AST_ARGUMENT);
853 assert(child->children.size() == 1);
854 children_list.push_back(child->children[0]);
855 child->children.clear();
856 delete child;
857 }
858 children.clear();
859
860 if (str == "bufif0" || str == "bufif1" || str == "notif0" || str == "notif1")
861 {
862 if (children_list.size() != 3)
863 log_error("Invalid number of arguments for primitive `%s' at %s:%d!\n",
864 str.c_str(), filename.c_str(), linenum);
865
866 std::vector<RTLIL::State> z_const(1, RTLIL::State::Sz);
867
868 AstNode *mux_input = children_list.at(1);
869 if (str == "notif0" || str == "notif1") {
870 mux_input = new AstNode(AST_BIT_NOT, mux_input);
871 }
872 AstNode *node = new AstNode(AST_TERNARY, children_list.at(2));
873 if (str == "bufif0") {
874 node->children.push_back(AstNode::mkconst_bits(z_const, false));
875 node->children.push_back(mux_input);
876 } else {
877 node->children.push_back(mux_input);
878 node->children.push_back(AstNode::mkconst_bits(z_const, false));
879 }
880
881 str.clear();
882 type = AST_ASSIGN;
883 children.push_back(children_list.at(0));
884 children.push_back(node);
885 did_something = true;
886 }
887 else
888 {
889 AstNodeType op_type = AST_NONE;
890 bool invert_results = false;
891
892 if (str == "and")
893 op_type = AST_BIT_AND;
894 if (str == "nand")
895 op_type = AST_BIT_AND, invert_results = true;
896 if (str == "or")
897 op_type = AST_BIT_OR;
898 if (str == "nor")
899 op_type = AST_BIT_OR, invert_results = true;
900 if (str == "xor")
901 op_type = AST_BIT_XOR;
902 if (str == "xnor")
903 op_type = AST_BIT_XOR, invert_results = true;
904 if (str == "buf")
905 op_type = AST_POS;
906 if (str == "not")
907 op_type = AST_POS, invert_results = true;
908 assert(op_type != AST_NONE);
909
910 AstNode *node = children_list[1];
911 if (op_type != AST_POS)
912 for (size_t i = 2; i < children_list.size(); i++)
913 node = new AstNode(op_type, node, children_list[i]);
914 if (invert_results)
915 node = new AstNode(AST_BIT_NOT, node);
916
917 str.clear();
918 type = AST_ASSIGN;
919 children.push_back(children_list[0]);
920 children.push_back(node);
921 did_something = true;
922 }
923 }
924
925 // replace dynamic ranges in left-hand side expressions (e.g. "foo[bar] <= 1'b1;") with
926 // a big case block that selects the correct single-bit assignment.
927 if (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) {
928 if (children[0]->type != AST_IDENTIFIER || children[0]->children.size() == 0)
929 goto skip_dynamic_range_lvalue_expansion;
930 if (children[0]->children[0]->range_valid || did_something)
931 goto skip_dynamic_range_lvalue_expansion;
932 if (children[0]->id2ast == NULL || children[0]->id2ast->type != AST_WIRE)
933 goto skip_dynamic_range_lvalue_expansion;
934 if (!children[0]->id2ast->range_valid)
935 goto skip_dynamic_range_lvalue_expansion;
936 int source_width = children[0]->id2ast->range_left - children[0]->id2ast->range_right + 1;
937 int result_width = 1;
938 AstNode *shift_expr = NULL;
939 AstNode *range = children[0]->children[0];
940 if (range->children.size() == 1) {
941 shift_expr = range->children[0]->clone();
942 } else {
943 shift_expr = range->children[1]->clone();
944 AstNode *left_at_zero_ast = range->children[0]->clone();
945 AstNode *right_at_zero_ast = range->children[1]->clone();
946 while (left_at_zero_ast->simplify(true, true, false, stage, -1, false)) { }
947 while (right_at_zero_ast->simplify(true, true, false, stage, -1, false)) { }
948 if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
949 log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n",
950 str.c_str(), filename.c_str(), linenum);
951 result_width = left_at_zero_ast->integer - right_at_zero_ast->integer + 1;
952 }
953 did_something = true;
954 newNode = new AstNode(AST_CASE, shift_expr);
955 for (int i = 0; i <= source_width-result_width; i++) {
956 int start_bit = children[0]->id2ast->range_right + i;
957 AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit, true));
958 AstNode *lvalue = children[0]->clone();
959 lvalue->delete_children();
960 lvalue->children.push_back(new AstNode(AST_RANGE,
961 mkconst_int(start_bit+result_width-1, true), mkconst_int(start_bit, true)));
962 cond->children.push_back(new AstNode(AST_BLOCK, new AstNode(type, lvalue, children[1]->clone())));
963 newNode->children.push_back(cond);
964 }
965 goto apply_newNode;
966 }
967 skip_dynamic_range_lvalue_expansion:;
968
969 if (stage > 1 && type == AST_ASSERT && current_block != NULL)
970 {
971 std::stringstream sstr;
972 sstr << "$assert$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++);
973 std::string id_check = sstr.str() + "_CHECK", id_en = sstr.str() + "_EN";
974
975 AstNode *wire_check = new AstNode(AST_WIRE);
976 wire_check->str = id_check;
977 current_ast_mod->children.push_back(wire_check);
978 current_scope[wire_check->str] = wire_check;
979 while (wire_check->simplify(true, false, false, 1, -1, false)) { }
980
981 AstNode *wire_en = new AstNode(AST_WIRE);
982 wire_en->str = id_en;
983 current_ast_mod->children.push_back(wire_en);
984 current_scope[wire_en->str] = wire_en;
985 while (wire_en->simplify(true, false, false, 1, -1, false)) { }
986
987 std::vector<RTLIL::State> x_bit;
988 x_bit.push_back(RTLIL::State::Sx);
989
990 AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bit, false));
991 assign_check->children[0]->str = id_check;
992
993 AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, 1));
994 assign_en->children[0]->str = id_en;
995
996 AstNode *default_signals = new AstNode(AST_BLOCK);
997 default_signals->children.push_back(assign_check);
998 default_signals->children.push_back(assign_en);
999 current_top_block->children.insert(current_top_block->children.begin(), default_signals);
1000
1001 assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone()));
1002 assign_check->children[0]->str = id_check;
1003
1004 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(1, false, 1));
1005 assign_en->children[0]->str = id_en;
1006
1007 newNode = new AstNode(AST_BLOCK);
1008 newNode->children.push_back(assign_check);
1009 newNode->children.push_back(assign_en);
1010
1011 AstNode *assertnode = new AstNode(AST_ASSERT);
1012 assertnode->children.push_back(new AstNode(AST_IDENTIFIER));
1013 assertnode->children.push_back(new AstNode(AST_IDENTIFIER));
1014 assertnode->children[0]->str = id_check;
1015 assertnode->children[1]->str = id_en;
1016 assertnode->attributes.swap(attributes);
1017 current_ast_mod->children.push_back(assertnode);
1018
1019 goto apply_newNode;
1020 }
1021
1022 if (stage > 1 && type == AST_ASSERT && children.size() == 1)
1023 {
1024 children[0] = new AstNode(AST_REDUCE_BOOL, children[0]->clone());
1025 children.push_back(mkconst_int(1, false, 1));
1026 did_something = true;
1027 }
1028
1029 // found right-hand side identifier for memory -> replace with memory read port
1030 if (stage > 1 && type == AST_IDENTIFIER && id2ast != NULL && id2ast->type == AST_MEMORY && !in_lvalue &&
1031 children[0]->type == AST_RANGE && children[0]->children.size() == 1) {
1032 newNode = new AstNode(AST_MEMRD, children[0]->children[0]->clone());
1033 newNode->str = str;
1034 newNode->id2ast = id2ast;
1035 goto apply_newNode;
1036 }
1037
1038 // assignment with memory in left-hand side expression -> replace with memory write port
1039 if (stage > 1 && (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) && children[0]->type == AST_IDENTIFIER &&
1040 children[0]->children.size() == 1 && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY &&
1041 children[0]->id2ast->children.size() >= 2 && children[0]->id2ast->children[0]->range_valid &&
1042 children[0]->id2ast->children[1]->range_valid)
1043 {
1044 std::stringstream sstr;
1045 sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++);
1046 std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA", id_en = sstr.str() + "_EN";
1047
1048 if (type == AST_ASSIGN_EQ)
1049 log("Warining: Blocking assignment to memory in line %s:%d is handled like a non-blocking assignment.\n",
1050 filename.c_str(), linenum);
1051
1052 int mem_width, mem_size, addr_bits;
1053 children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
1054
1055 AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
1056 wire_addr->str = id_addr;
1057 current_ast_mod->children.push_back(wire_addr);
1058 current_scope[wire_addr->str] = wire_addr;
1059 while (wire_addr->simplify(true, false, false, 1, -1, false)) { }
1060
1061 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
1062 wire_data->str = id_data;
1063 current_ast_mod->children.push_back(wire_data);
1064 current_scope[wire_data->str] = wire_data;
1065 while (wire_data->simplify(true, false, false, 1, -1, false)) { }
1066
1067 AstNode *wire_en = new AstNode(AST_WIRE);
1068 wire_en->str = id_en;
1069 current_ast_mod->children.push_back(wire_en);
1070 current_scope[wire_en->str] = wire_en;
1071 while (wire_en->simplify(true, false, false, 1, -1, false)) { }
1072
1073 std::vector<RTLIL::State> x_bits;
1074 for (int i = 0; i < mem_width; i++)
1075 x_bits.push_back(RTLIL::State::Sx);
1076
1077 AstNode *assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits, false));
1078 assign_addr->children[0]->str = id_addr;
1079
1080 AstNode *assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits, false));
1081 assign_data->children[0]->str = id_data;
1082
1083 AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, 1));
1084 assign_en->children[0]->str = id_en;
1085
1086 AstNode *default_signals = new AstNode(AST_BLOCK);
1087 default_signals->children.push_back(assign_addr);
1088 default_signals->children.push_back(assign_data);
1089 default_signals->children.push_back(assign_en);
1090 current_top_block->children.insert(current_top_block->children.begin(), default_signals);
1091
1092 assign_addr = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());
1093 assign_addr->children[0]->str = id_addr;
1094
1095 assign_data = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), children[1]->clone());
1096 assign_data->children[0]->str = id_data;
1097
1098 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(1, false, 1));
1099 assign_en->children[0]->str = id_en;
1100
1101 newNode = new AstNode(AST_BLOCK);
1102 newNode->children.push_back(assign_addr);
1103 newNode->children.push_back(assign_data);
1104 newNode->children.push_back(assign_en);
1105
1106 AstNode *wrnode = new AstNode(AST_MEMWR);
1107 wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
1108 wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
1109 wrnode->children.push_back(new AstNode(AST_IDENTIFIER));
1110 wrnode->str = children[0]->str;
1111 wrnode->children[0]->str = id_addr;
1112 wrnode->children[1]->str = id_data;
1113 wrnode->children[2]->str = id_en;
1114 current_ast_mod->children.push_back(wrnode);
1115
1116 goto apply_newNode;
1117 }
1118
1119 // replace function and task calls with the code from the function or task
1120 if ((type == AST_FCALL || type == AST_TCALL) && !str.empty())
1121 {
1122 if (type == AST_FCALL)
1123 {
1124 if (str == "\\$clog2")
1125 {
1126 AstNode *buf = children[0]->clone();
1127 while (buf->simplify(true, false, false, stage, width_hint, sign_hint)) { }
1128 if (buf->type != AST_CONSTANT)
1129 log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
1130
1131 RTLIL::Const arg_value = buf->bitsAsConst();
1132 uint32_t result = 0;
1133 for (size_t i = 0; i < arg_value.bits.size(); i++)
1134 if (arg_value.bits.at(i) == RTLIL::State::S1)
1135 result = i;
1136
1137 newNode = mkconst_int(result, false);
1138 goto apply_newNode;
1139 }
1140
1141 if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION)
1142 log_error("Can't resolve function name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
1143 }
1144 if (type == AST_TCALL) {
1145 if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK)
1146 log_error("Can't resolve task name `%s' at %s:%d.\n", str.c_str(), filename.c_str(), linenum);
1147 }
1148
1149 AstNode *decl = current_scope[str];
1150 std::stringstream sstr;
1151 sstr << "$func$" << str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++) << "$";
1152 std::string prefix = sstr.str();
1153
1154 size_t arg_count = 0;
1155 std::map<std::string, std::string> replace_rules;
1156
1157 if (current_block == NULL)
1158 {
1159 assert(type == AST_FCALL);
1160
1161 AstNode *wire = NULL;
1162 for (auto child : decl->children)
1163 if (child->type == AST_WIRE && child->str == str)
1164 wire = child->clone();
1165 assert(wire != NULL);
1166
1167 wire->str = prefix + str;
1168 wire->port_id = 0;
1169 wire->is_input = false;
1170 wire->is_output = false;
1171
1172 current_ast_mod->children.push_back(wire);
1173 while (wire->simplify(true, false, false, 1, -1, false)) { }
1174
1175 AstNode *lvalue = new AstNode(AST_IDENTIFIER);
1176 lvalue->str = wire->str;
1177
1178 AstNode *always = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK,
1179 new AstNode(AST_ASSIGN_EQ, lvalue, clone())));
1180 current_ast_mod->children.push_back(always);
1181
1182 goto replace_fcall_with_id;
1183 }
1184
1185 for (auto child : decl->children)
1186 {
1187 if (child->type == AST_WIRE)
1188 {
1189 AstNode *wire = child->clone();
1190 wire->str = prefix + wire->str;
1191 wire->port_id = 0;
1192 wire->is_input = false;
1193 wire->is_output = false;
1194 current_ast_mod->children.push_back(wire);
1195 while (wire->simplify(true, false, false, 1, -1, false)) { }
1196
1197 replace_rules[child->str] = wire->str;
1198
1199 if (child->is_input && arg_count < children.size())
1200 {
1201 AstNode *arg = children[arg_count++]->clone();
1202 AstNode *wire_id = new AstNode(AST_IDENTIFIER);
1203 wire_id->str = wire->str;
1204 AstNode *assign = new AstNode(AST_ASSIGN_EQ, wire_id, arg);
1205
1206 for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) {
1207 if (*it != current_block_child)
1208 continue;
1209 current_block->children.insert(it, assign);
1210 break;
1211 }
1212 }
1213 }
1214 else
1215 {
1216 AstNode *stmt = child->clone();
1217 stmt->replace_ids(replace_rules);
1218
1219 for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) {
1220 if (*it != current_block_child)
1221 continue;
1222 current_block->children.insert(it, stmt);
1223 break;
1224 }
1225 }
1226 }
1227
1228 replace_fcall_with_id:
1229 if (type == AST_FCALL) {
1230 delete_children();
1231 type = AST_IDENTIFIER;
1232 str = prefix + str;
1233 }
1234 if (type == AST_TCALL)
1235 str = "";
1236 did_something = true;
1237 }
1238
1239 // perform const folding when activated
1240 if (const_fold && newNode == NULL)
1241 {
1242 bool string_op;
1243 std::vector<RTLIL::State> tmp_bits;
1244 RTLIL::Const (*const_func)(const RTLIL::Const&, const RTLIL::Const&, bool, bool, int);
1245 RTLIL::Const dummy_arg;
1246
1247 switch (type)
1248 {
1249 case AST_IDENTIFIER:
1250 if (current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM)) {
1251 if (current_scope[str]->children[0]->type == AST_CONSTANT) {
1252 if (children.size() != 0 && children[0]->type == AST_RANGE && children[0]->range_valid) {
1253 std::vector<RTLIL::State> data;
1254 for (int i = children[0]->range_right; i <= children[0]->range_left; i++)
1255 data.push_back(current_scope[str]->children[0]->bits[i]);
1256 newNode = mkconst_bits(data, false);
1257 } else
1258 if (children.size() == 0)
1259 newNode = current_scope[str]->children[0]->clone();
1260 }
1261 }
1262 else if (at_zero && current_scope.count(str) > 0 && (current_scope[str]->type == AST_WIRE || current_scope[str]->type == AST_AUTOWIRE)) {
1263 newNode = mkconst_int(0, sign_hint, width_hint);
1264 }
1265 break;
1266 case AST_BIT_NOT:
1267 if (children[0]->type == AST_CONSTANT) {
1268 RTLIL::Const y = RTLIL::const_not(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint);
1269 newNode = mkconst_bits(y.bits, sign_hint);
1270 }
1271 break;
1272 case AST_TO_SIGNED:
1273 case AST_TO_UNSIGNED:
1274 if (children[0]->type == AST_CONSTANT) {
1275 RTLIL::Const y = children[0]->bitsAsConst(width_hint, sign_hint);
1276 newNode = mkconst_bits(y.bits, type == AST_TO_SIGNED);
1277 }
1278 break;
1279 if (0) { case AST_BIT_AND: const_func = RTLIL::const_and; }
1280 if (0) { case AST_BIT_OR: const_func = RTLIL::const_or; }
1281 if (0) { case AST_BIT_XOR: const_func = RTLIL::const_xor; }
1282 if (0) { case AST_BIT_XNOR: const_func = RTLIL::const_xnor; }
1283 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
1284 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
1285 children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint);
1286 newNode = mkconst_bits(y.bits, sign_hint);
1287 }
1288 break;
1289 if (0) { case AST_REDUCE_AND: const_func = RTLIL::const_reduce_and; }
1290 if (0) { case AST_REDUCE_OR: const_func = RTLIL::const_reduce_or; }
1291 if (0) { case AST_REDUCE_XOR: const_func = RTLIL::const_reduce_xor; }
1292 if (0) { case AST_REDUCE_XNOR: const_func = RTLIL::const_reduce_xnor; }
1293 if (0) { case AST_REDUCE_BOOL: const_func = RTLIL::const_reduce_bool; }
1294 if (children[0]->type == AST_CONSTANT) {
1295 RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), dummy_arg, false, false, -1);
1296 newNode = mkconst_bits(y.bits, false);
1297 }
1298 break;
1299 case AST_LOGIC_NOT:
1300 if (children[0]->type == AST_CONSTANT) {
1301 RTLIL::Const y = RTLIL::const_logic_not(RTLIL::Const(children[0]->bits), dummy_arg, children[0]->is_signed, false, -1);
1302 newNode = mkconst_bits(y.bits, false);
1303 }
1304 break;
1305 if (0) { case AST_LOGIC_AND: const_func = RTLIL::const_logic_and; }
1306 if (0) { case AST_LOGIC_OR: const_func = RTLIL::const_logic_or; }
1307 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
1308 RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), RTLIL::Const(children[1]->bits),
1309 children[0]->is_signed, children[1]->is_signed, -1);
1310 newNode = mkconst_bits(y.bits, false);
1311 }
1312 break;
1313 if (0) { case AST_SHIFT_LEFT: const_func = RTLIL::const_shl; }
1314 if (0) { case AST_SHIFT_RIGHT: const_func = RTLIL::const_shr; }
1315 if (0) { case AST_SHIFT_SLEFT: const_func = RTLIL::const_sshl; }
1316 if (0) { case AST_SHIFT_SRIGHT: const_func = RTLIL::const_sshr; }
1317 if (0) { case AST_POW: const_func = RTLIL::const_pow; }
1318 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
1319 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
1320 RTLIL::Const(children[1]->bits), sign_hint, type == AST_POW ? children[1]->is_signed : false, width_hint);
1321 newNode = mkconst_bits(y.bits, sign_hint);
1322 }
1323 break;
1324 if (0) { case AST_LT: const_func = RTLIL::const_lt; }
1325 if (0) { case AST_LE: const_func = RTLIL::const_le; }
1326 if (0) { case AST_EQ: const_func = RTLIL::const_eq; }
1327 if (0) { case AST_NE: const_func = RTLIL::const_ne; }
1328 if (0) { case AST_EQX: const_func = RTLIL::const_eqx; }
1329 if (0) { case AST_NEX: const_func = RTLIL::const_nex; }
1330 if (0) { case AST_GE: const_func = RTLIL::const_ge; }
1331 if (0) { case AST_GT: const_func = RTLIL::const_gt; }
1332 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
1333 int cmp_width = std::max(children[0]->bits.size(), children[1]->bits.size());
1334 bool cmp_signed = children[0]->is_signed && children[1]->is_signed;
1335 RTLIL::Const y = const_func(children[0]->bitsAsConst(cmp_width, cmp_signed),
1336 children[1]->bitsAsConst(cmp_width, cmp_signed), cmp_signed, cmp_signed, 1);
1337 newNode = mkconst_bits(y.bits, false);
1338 }
1339 break;
1340 if (0) { case AST_ADD: const_func = RTLIL::const_add; }
1341 if (0) { case AST_SUB: const_func = RTLIL::const_sub; }
1342 if (0) { case AST_MUL: const_func = RTLIL::const_mul; }
1343 if (0) { case AST_DIV: const_func = RTLIL::const_div; }
1344 if (0) { case AST_MOD: const_func = RTLIL::const_mod; }
1345 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
1346 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
1347 children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint);
1348 newNode = mkconst_bits(y.bits, sign_hint);
1349 }
1350 break;
1351 if (0) { case AST_POS: const_func = RTLIL::const_pos; }
1352 if (0) { case AST_NEG: const_func = RTLIL::const_neg; }
1353 if (children[0]->type == AST_CONSTANT) {
1354 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint);
1355 newNode = mkconst_bits(y.bits, sign_hint);
1356 }
1357 break;
1358 case AST_TERNARY:
1359 if (children[0]->type == AST_CONSTANT) {
1360 bool found_sure_true = false;
1361 bool found_maybe_true = false;
1362 for (auto &bit : children[0]->bits) {
1363 if (bit == RTLIL::State::S1)
1364 found_sure_true = true;
1365 if (bit > RTLIL::State::S1)
1366 found_maybe_true = true;
1367 }
1368 AstNode *choice = NULL;
1369 if (found_sure_true)
1370 choice = children[1];
1371 else if (!found_maybe_true)
1372 choice = children[2];
1373 if (choice != NULL && choice->type == AST_CONSTANT) {
1374 RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint);
1375 if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false)
1376 newNode = mkconst_str(y.bits);
1377 else
1378 newNode = mkconst_bits(y.bits, sign_hint);
1379 } else if (children[1]->type == AST_CONSTANT && children[2]->type == AST_CONSTANT) {
1380 RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint);
1381 RTLIL::Const b = children[2]->bitsAsConst(width_hint, sign_hint);
1382 assert(a.bits.size() == b.bits.size());
1383 for (size_t i = 0; i < a.bits.size(); i++)
1384 if (a.bits[i] != b.bits[i])
1385 a.bits[i] = RTLIL::State::Sx;
1386 newNode = mkconst_bits(a.bits, sign_hint);
1387 }
1388 }
1389 break;
1390 case AST_CONCAT:
1391 string_op = !children.empty();
1392 for (auto it = children.begin(); it != children.end(); it++) {
1393 if ((*it)->type != AST_CONSTANT)
1394 goto not_const;
1395 if (!(*it)->is_string)
1396 string_op = false;
1397 tmp_bits.insert(tmp_bits.end(), (*it)->bits.begin(), (*it)->bits.end());
1398 }
1399 newNode = string_op ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false);
1400 break;
1401 case AST_REPLICATE:
1402 if (children.at(0)->type != AST_CONSTANT || children.at(1)->type != AST_CONSTANT)
1403 goto not_const;
1404 for (int i = 0; i < children[0]->bitsAsConst().as_int(); i++)
1405 tmp_bits.insert(tmp_bits.end(), children.at(1)->bits.begin(), children.at(1)->bits.end());
1406 newNode = children.at(1)->is_string ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false);
1407 break;
1408 default:
1409 not_const:
1410 break;
1411 }
1412 }
1413
1414 // if any of the above set 'newNode' -> use 'newNode' as template to update 'this'
1415 if (newNode) {
1416 apply_newNode:
1417 // fprintf(stderr, "----\n");
1418 // dumpAst(stderr, "- ");
1419 // newNode->dumpAst(stderr, "+ ");
1420 assert(newNode != NULL);
1421 newNode->filename = filename;
1422 newNode->linenum = linenum;
1423 newNode->cloneInto(this);
1424 delete newNode;
1425 did_something = true;
1426 }
1427
1428 return did_something;
1429 }
1430
1431 static void replace_result_wire_name_in_function(AstNode *node, std::string &from, std::string &to)
1432 {
1433 for (auto &it : node->children)
1434 replace_result_wire_name_in_function(it, from, to);
1435 if (node->str == from)
1436 node->str = to;
1437 }
1438
1439 // annotate the names of all wires and other named objects in a generate block
1440 void AstNode::expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map)
1441 {
1442 if (!index_var.empty() && type == AST_IDENTIFIER && str == index_var) {
1443 current_scope[index_var]->children[0]->cloneInto(this);
1444 return;
1445 }
1446
1447 if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL) && name_map.count(str) > 0)
1448 str = name_map[str];
1449
1450 std::map<std::string, std::string> backup_name_map;
1451
1452 for (size_t i = 0; i < children.size(); i++) {
1453 AstNode *child = children[i];
1454 if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM ||
1455 child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL) {
1456 if (backup_name_map.size() == 0)
1457 backup_name_map = name_map;
1458 std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix;
1459 size_t pos = child->str.rfind('.');
1460 if (pos == std::string::npos)
1461 pos = child->str[0] == '\\' ? 1 : 0;
1462 else
1463 pos = pos + 1;
1464 new_name = child->str.substr(0, pos) + new_name + child->str.substr(pos);
1465 if (new_name[0] != '$' && new_name[0] != '\\')
1466 new_name = prefix[0] + new_name;
1467 name_map[child->str] = new_name;
1468 if (child->type == AST_FUNCTION)
1469 replace_result_wire_name_in_function(child, child->str, new_name);
1470 else
1471 child->str = new_name;
1472 current_scope[new_name] = child;
1473 }
1474 }
1475
1476 for (size_t i = 0; i < children.size(); i++) {
1477 AstNode *child = children[i];
1478 if (child->type != AST_FUNCTION && child->type != AST_TASK)
1479 child->expand_genblock(index_var, prefix, name_map);
1480 }
1481
1482 if (backup_name_map.size() > 0)
1483 name_map.swap(backup_name_map);
1484 }
1485
1486 // rename stuff (used when tasks of functions are instanciated)
1487 void AstNode::replace_ids(std::map<std::string, std::string> &rules)
1488 {
1489 if (type == AST_IDENTIFIER && rules.count(str) > 0)
1490 str = rules[str];
1491 for (auto child : children)
1492 child->replace_ids(rules);
1493 }
1494
1495 // find memories that should be replaced by registers
1496 void AstNode::mem2reg_as_needed_pass1(std::map<AstNode*, std::set<std::string>> &mem2reg_places,
1497 std::map<AstNode*, uint32_t> &mem2reg_candidates, std::map<AstNode*, uint32_t> &proc_flags, uint32_t &flags)
1498 {
1499 uint32_t children_flags = 0;
1500 int ignore_children_counter = 0;
1501
1502 if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ)
1503 {
1504 if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY)
1505 {
1506 AstNode *mem = children[0]->id2ast;
1507
1508 // activate mem2reg if this is assigned in an async proc
1509 if (flags & AstNode::MEM2REG_FL_ASYNC) {
1510 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ASYNC))
1511 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
1512 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ASYNC;
1513 }
1514
1515 // remember if this is assigned blocking (=)
1516 if (type == AST_ASSIGN_EQ) {
1517 if (!(proc_flags[mem] & AstNode::MEM2REG_FL_EQ1))
1518 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
1519 proc_flags[mem] |= AstNode::MEM2REG_FL_EQ1;
1520 }
1521
1522 // remember where this is
1523 if (flags & MEM2REG_FL_INIT) {
1524 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_INIT))
1525 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
1526 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_INIT;
1527 } else {
1528 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ELSE))
1529 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
1530 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ELSE;
1531 }
1532 }
1533
1534 ignore_children_counter = 1;
1535 }
1536
1537 if (type == AST_IDENTIFIER && id2ast && id2ast->type == AST_MEMORY)
1538 {
1539 AstNode *mem = id2ast;
1540
1541 // flag if used after blocking assignment (in same proc)
1542 if ((proc_flags[mem] & AstNode::MEM2REG_FL_EQ1) && !(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_EQ2)) {
1543 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), linenum));
1544 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_EQ2;
1545 }
1546 }
1547
1548 // also activate if requested, either by using mem2reg attribute or by declaring array as 'wire' instead of 'reg'
1549 if (type == AST_MEMORY && (get_bool_attribute("\\mem2reg") || (flags & AstNode::MEM2REG_FL_ALL) || !is_reg))
1550 mem2reg_candidates[this] |= AstNode::MEM2REG_FL_FORCED;
1551
1552 if (type == AST_MODULE && get_bool_attribute("\\mem2reg"))
1553 children_flags |= AstNode::MEM2REG_FL_ALL;
1554
1555 std::map<AstNode*, uint32_t> *proc_flags_p = NULL;
1556
1557 if (type == AST_ALWAYS) {
1558 int count_edge_events = 0;
1559 for (auto child : children)
1560 if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE)
1561 count_edge_events++;
1562 if (count_edge_events != 1)
1563 children_flags |= AstNode::MEM2REG_FL_ASYNC;
1564 proc_flags_p = new std::map<AstNode*, uint32_t>;
1565 }
1566
1567 if (type == AST_INITIAL) {
1568 children_flags |= AstNode::MEM2REG_FL_INIT;
1569 proc_flags_p = new std::map<AstNode*, uint32_t>;
1570 }
1571
1572 uint32_t backup_flags = flags;
1573 flags |= children_flags;
1574 assert((flags & ~0x000000ff) == 0);
1575
1576 for (auto child : children)
1577 if (ignore_children_counter > 0)
1578 ignore_children_counter--;
1579 else if (proc_flags_p)
1580 child->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, *proc_flags_p, flags);
1581 else
1582 child->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, proc_flags, flags);
1583
1584 flags &= ~children_flags | backup_flags;
1585
1586 if (proc_flags_p) {
1587 for (auto it : *proc_flags_p)
1588 assert((it.second & ~0xff000000) == 0);
1589 delete proc_flags_p;
1590 }
1591 }
1592
1593 // actually replace memories with registers
1594 void AstNode::mem2reg_as_needed_pass2(std::set<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block)
1595 {
1596 if (type == AST_BLOCK)
1597 block = this;
1598
1599 if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && block != NULL && children[0]->id2ast &&
1600 mem2reg_set.count(children[0]->id2ast) > 0 && children[0]->children[0]->children[0]->type != AST_CONSTANT)
1601 {
1602 std::stringstream sstr;
1603 sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++);
1604 std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
1605
1606 int mem_width, mem_size, addr_bits;
1607 children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
1608
1609 AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
1610 wire_addr->str = id_addr;
1611 wire_addr->is_reg = true;
1612 wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
1613 mod->children.push_back(wire_addr);
1614 while (wire_addr->simplify(true, false, false, 1, -1, false)) { }
1615
1616 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
1617 wire_data->str = id_data;
1618 wire_data->is_reg = true;
1619 wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
1620 mod->children.push_back(wire_data);
1621 while (wire_data->simplify(true, false, false, 1, -1, false)) { }
1622
1623 assert(block != NULL);
1624 size_t assign_idx = 0;
1625 while (assign_idx < block->children.size() && block->children[assign_idx] != this)
1626 assign_idx++;
1627 assert(assign_idx < block->children.size());
1628
1629 AstNode *assign_addr = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());
1630 assign_addr->children[0]->str = id_addr;
1631 block->children.insert(block->children.begin()+assign_idx+1, assign_addr);
1632
1633 AstNode *case_node = new AstNode(AST_CASE, new AstNode(AST_IDENTIFIER));
1634 case_node->children[0]->str = id_addr;
1635 for (int i = 0; i < mem_size; i++) {
1636 if (children[0]->children[0]->children[0]->type == AST_CONSTANT && int(children[0]->children[0]->children[0]->integer) != i)
1637 continue;
1638 AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK));
1639 AstNode *assign_reg = new AstNode(type, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER));
1640 assign_reg->children[0]->str = stringf("%s[%d]", children[0]->str.c_str(), i);
1641 assign_reg->children[1]->str = id_data;
1642 cond_node->children[1]->children.push_back(assign_reg);
1643 case_node->children.push_back(cond_node);
1644 }
1645 block->children.insert(block->children.begin()+assign_idx+2, case_node);
1646
1647 children[0]->delete_children();
1648 children[0]->range_valid = false;
1649 children[0]->id2ast = NULL;
1650 children[0]->str = id_data;
1651 type = AST_ASSIGN_EQ;
1652 }
1653
1654 if (type == AST_IDENTIFIER && id2ast && mem2reg_set.count(id2ast) > 0)
1655 {
1656 if (children[0]->children[0]->type == AST_CONSTANT)
1657 {
1658 int id = children[0]->children[0]->integer;
1659 str = stringf("%s[%d]", str.c_str(), id);
1660
1661 delete_children();
1662 range_valid = false;
1663 id2ast = NULL;
1664 }
1665 else
1666 {
1667 std::stringstream sstr;
1668 sstr << "$mem2reg_rd$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (RTLIL::autoidx++);
1669 std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
1670
1671 int mem_width, mem_size, addr_bits;
1672 id2ast->meminfo(mem_width, mem_size, addr_bits);
1673
1674 AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
1675 wire_addr->str = id_addr;
1676 wire_addr->is_reg = true;
1677 if (block)
1678 wire_addr->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
1679 mod->children.push_back(wire_addr);
1680 while (wire_addr->simplify(true, false, false, 1, -1, false)) { }
1681
1682 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
1683 wire_data->str = id_data;
1684 wire_data->is_reg = true;
1685 if (block)
1686 wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
1687 mod->children.push_back(wire_data);
1688 while (wire_data->simplify(true, false, false, 1, -1, false)) { }
1689
1690 AstNode *assign_addr = new AstNode(block ? AST_ASSIGN_EQ : AST_ASSIGN, new AstNode(AST_IDENTIFIER), children[0]->children[0]->clone());
1691 assign_addr->children[0]->str = id_addr;
1692
1693 AstNode *case_node = new AstNode(AST_CASE, new AstNode(AST_IDENTIFIER));
1694 case_node->children[0]->str = id_addr;
1695
1696 for (int i = 0; i < mem_size; i++) {
1697 if (children[0]->children[0]->type == AST_CONSTANT && int(children[0]->children[0]->integer) != i)
1698 continue;
1699 AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK));
1700 AstNode *assign_reg = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER));
1701 assign_reg->children[0]->str = id_data;
1702 assign_reg->children[1]->str = stringf("%s[%d]", str.c_str(), i);
1703 cond_node->children[1]->children.push_back(assign_reg);
1704 case_node->children.push_back(cond_node);
1705 }
1706
1707 std::vector<RTLIL::State> x_bits;
1708 for (int i = 0; i < mem_width; i++)
1709 x_bits.push_back(RTLIL::State::Sx);
1710
1711 AstNode *cond_node = new AstNode(AST_COND, new AstNode(AST_DEFAULT), new AstNode(AST_BLOCK));
1712 AstNode *assign_reg = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), AstNode::mkconst_bits(x_bits, false));
1713 assign_reg->children[0]->str = id_data;
1714 cond_node->children[1]->children.push_back(assign_reg);
1715 case_node->children.push_back(cond_node);
1716
1717 if (block)
1718 {
1719 size_t assign_idx = 0;
1720 while (assign_idx < block->children.size() && !block->children[assign_idx]->contains(this))
1721 assign_idx++;
1722 assert(assign_idx < block->children.size());
1723 block->children.insert(block->children.begin()+assign_idx, case_node);
1724 block->children.insert(block->children.begin()+assign_idx, assign_addr);
1725 }
1726 else
1727 {
1728 AstNode *proc = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
1729 proc->children[0]->children.push_back(case_node);
1730 mod->children.push_back(proc);
1731 mod->children.push_back(assign_addr);
1732 }
1733
1734 delete_children();
1735 range_valid = false;
1736 id2ast = NULL;
1737 str = id_data;
1738 }
1739 }
1740
1741 assert(id2ast == NULL || mem2reg_set.count(id2ast) == 0);
1742
1743 auto children_list = children;
1744 for (size_t i = 0; i < children_list.size(); i++)
1745 children_list[i]->mem2reg_as_needed_pass2(mem2reg_set, mod, block);
1746 }
1747
1748 // calulate memory dimensions
1749 void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits)
1750 {
1751 assert(type == AST_MEMORY);
1752
1753 mem_width = children[0]->range_left - children[0]->range_right + 1;
1754 mem_size = children[1]->range_left - children[1]->range_right;
1755
1756 if (mem_size < 0)
1757 mem_size *= -1;
1758 mem_size += std::min(children[1]->range_left, children[1]->range_right) + 1;
1759
1760 addr_bits = 1;
1761 while ((1 << addr_bits) < mem_size)
1762 addr_bits++;
1763 }
1764