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