verilog: fix multiple AST_PREFIX scope resolution issues
[yosys.git] / frontends / ast / simplify.cc
1 /*
2 * yosys -- Yosys Open SYnthesis Suite
3 *
4 * Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
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 && len_value != 0)
93 goto unsupported_format;
94 YS_FALLTHROUGH
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 case 'l':
114 case 'L':
115 if (got_len)
116 goto unsupported_format;
117 break;
118
119 default:
120 unsupported_format:
121 log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str());
122 break;
123 }
124
125 switch (cformat)
126 {
127 case 's':
128 case 'S':
129 sout += node_arg->bitsAsConst().decode_string();
130 break;
131
132 case 'd':
133 case 'D':
134 sout += stringf("%d", node_arg->bitsAsConst().as_int());
135 break;
136
137 case 'x':
138 case 'X':
139 {
140 Const val = node_arg->bitsAsConst();
141
142 while (GetSize(val) % 4 != 0)
143 val.bits.push_back(State::S0);
144
145 int len = GetSize(val) / 4;
146 for (int i = len; i < len_value; i++)
147 sout += got_zlen ? '0' : ' ';
148
149 for (int i = len-1; i >= 0; i--) {
150 Const digit = val.extract(4*i, 4);
151 if (digit.is_fully_def())
152 sout += stringf(cformat == 'x' ? "%x" : "%X", digit.as_int());
153 else
154 sout += cformat == 'x' ? "x" : "X";
155 }
156 }
157 break;
158
159 case 'm':
160 case 'M':
161 sout += log_id(current_module->name);
162 break;
163
164 case 'l':
165 case 'L':
166 sout += log_id(current_module->name);
167 break;
168
169 default:
170 log_abort();
171 }
172 }
173
174 // not a format specifier
175 else
176 sout += sformat[i];
177 }
178 return sout;
179 }
180
181
182 void AstNode::annotateTypedEnums(AstNode *template_node)
183 {
184 //check if enum
185 if (template_node->attributes.count(ID::enum_type)) {
186 //get reference to enum node:
187 std::string enum_type = template_node->attributes[ID::enum_type]->str.c_str();
188 // log("enum_type=%s (count=%lu)\n", enum_type.c_str(), current_scope.count(enum_type));
189 // log("current scope:\n");
190 // for (auto &it : current_scope)
191 // log(" %s\n", it.first.c_str());
192 log_assert(current_scope.count(enum_type) == 1);
193 AstNode *enum_node = current_scope.at(enum_type);
194 log_assert(enum_node->type == AST_ENUM);
195 while (enum_node->simplify(true, false, false, 1, -1, false, true)) { }
196 //get width from 1st enum item:
197 log_assert(enum_node->children.size() >= 1);
198 AstNode *enum_item0 = enum_node->children[0];
199 log_assert(enum_item0->type == AST_ENUM_ITEM);
200 int width;
201 if (!enum_item0->range_valid)
202 width = 1;
203 else if (enum_item0->range_swapped)
204 width = enum_item0->range_right - enum_item0->range_left + 1;
205 else
206 width = enum_item0->range_left - enum_item0->range_right + 1;
207 log_assert(width > 0);
208 //add declared enum items:
209 for (auto enum_item : enum_node->children){
210 log_assert(enum_item->type == AST_ENUM_ITEM);
211 //get is_signed
212 bool is_signed;
213 if (enum_item->children.size() == 1){
214 is_signed = false;
215 } else if (enum_item->children.size() == 2){
216 log_assert(enum_item->children[1]->type == AST_RANGE);
217 is_signed = enum_item->children[1]->is_signed;
218 } else {
219 log_error("enum_item children size==%lu, expected 1 or 2 for %s (%s)\n",
220 enum_item->children.size(),
221 enum_item->str.c_str(), enum_node->str.c_str()
222 );
223 }
224 //start building attribute string
225 std::string enum_item_str = "\\enum_value_";
226 //get enum item value
227 if(enum_item->children[0]->type != AST_CONSTANT){
228 log_error("expected const, got %s for %s (%s)\n",
229 type2str(enum_item->children[0]->type).c_str(),
230 enum_item->str.c_str(), enum_node->str.c_str()
231 );
232 }
233 RTLIL::Const val = enum_item->children[0]->bitsAsConst(width, is_signed);
234 enum_item_str.append(val.as_string());
235 //set attribute for available val to enum item name mappings
236 attributes[enum_item_str.c_str()] = mkconst_str(enum_item->str);
237 }
238 }
239 }
240
241 static bool name_has_dot(const std::string &name, std::string &struct_name)
242 {
243 // check if plausible struct member name \sss.mmm
244 std::string::size_type pos;
245 if (name.substr(0, 1) == "\\" && (pos = name.find('.', 0)) != std::string::npos) {
246 struct_name = name.substr(0, pos);
247 return true;
248 }
249 return false;
250 }
251
252 static AstNode *make_range(int left, int right, bool is_signed = false)
253 {
254 // generate a pre-validated range node for a fixed signal range.
255 auto range = new AstNode(AST_RANGE);
256 range->range_left = left;
257 range->range_right = right;
258 range->range_valid = true;
259 range->children.push_back(AstNode::mkconst_int(left, true));
260 range->children.push_back(AstNode::mkconst_int(right, true));
261 range->is_signed = is_signed;
262 return range;
263 }
264
265 static int range_width(AstNode *node, AstNode *rnode)
266 {
267 log_assert(rnode->type==AST_RANGE);
268 if (!rnode->range_valid) {
269 log_file_error(node->filename, node->location.first_line, "Size must be constant in packed struct/union member %s\n", node->str.c_str());
270
271 }
272 // note: range swapping has already been checked for
273 return rnode->range_left - rnode->range_right + 1;
274 }
275
276 [[noreturn]] static void struct_array_packing_error(AstNode *node)
277 {
278 log_file_error(node->filename, node->location.first_line, "Unpacked array in packed struct/union member %s\n", node->str.c_str());
279 }
280
281 static void save_struct_array_width(AstNode *node, int width)
282 {
283 // stash the stride for the array
284 node->multirange_dimensions.push_back(width);
285
286 }
287
288 static int get_struct_array_width(AstNode *node)
289 {
290 // the stride for the array, 1 if not an array
291 return (node->multirange_dimensions.empty() ? 1 : node->multirange_dimensions.back());
292
293 }
294
295 static int size_packed_struct(AstNode *snode, int base_offset)
296 {
297 // Struct members will be laid out in the structure contiguously from left to right.
298 // Union members all have zero offset from the start of the union.
299 // Determine total packed size and assign offsets. Store these in the member node.
300 bool is_union = (snode->type == AST_UNION);
301 int offset = 0;
302 int packed_width = -1;
303 // examine members from last to first
304 for (auto it = snode->children.rbegin(); it != snode->children.rend(); ++it) {
305 auto node = *it;
306 int width;
307 if (node->type == AST_STRUCT || node->type == AST_UNION) {
308 // embedded struct or union
309 width = size_packed_struct(node, base_offset + offset);
310 }
311 else {
312 log_assert(node->type == AST_STRUCT_ITEM);
313 if (node->children.size() > 0 && node->children[0]->type == AST_RANGE) {
314 // member width e.g. bit [7:0] a
315 width = range_width(node, node->children[0]);
316 if (node->children.size() == 2) {
317 if (node->children[1]->type == AST_RANGE) {
318 // unpacked array e.g. bit [63:0] a [0:3]
319 auto rnode = node->children[1];
320 int array_count = range_width(node, rnode);
321 if (array_count == 1) {
322 // C-type array size e.g. bit [63:0] a [4]
323 array_count = rnode->range_left;
324 }
325 save_struct_array_width(node, width);
326 width *= array_count;
327 }
328 else {
329 // array element must be single bit for a packed array
330 struct_array_packing_error(node);
331 }
332 }
333 // range nodes are now redundant
334 for (AstNode *child : node->children)
335 delete child;
336 node->children.clear();
337 }
338 else if (node->children.size() == 1 && node->children[0]->type == AST_MULTIRANGE) {
339 // packed 2D array, e.g. bit [3:0][63:0] a
340 auto rnode = node->children[0];
341 if (rnode->children.size() != 2) {
342 // packed arrays can only be 2D
343 struct_array_packing_error(node);
344 }
345 int array_count = range_width(node, rnode->children[0]);
346 width = range_width(node, rnode->children[1]);
347 save_struct_array_width(node, width);
348 width *= array_count;
349 // range nodes are now redundant
350 for (AstNode *child : node->children)
351 delete child;
352 node->children.clear();
353 }
354 else if (node->range_left < 0) {
355 // 1 bit signal: bit, logic or reg
356 width = 1;
357 }
358 else {
359 // already resolved and compacted
360 width = node->range_left - node->range_right + 1;
361 }
362 if (is_union) {
363 node->range_right = base_offset;
364 node->range_left = base_offset + width - 1;
365 }
366 else {
367 node->range_right = base_offset + offset;
368 node->range_left = base_offset + offset + width - 1;
369 }
370 node->range_valid = true;
371 }
372 if (is_union) {
373 // check that all members have the same size
374 if (packed_width == -1) {
375 // first member
376 packed_width = width;
377 }
378 else {
379 if (packed_width != width) {
380
381 log_file_error(node->filename, node->location.first_line, "member %s of a packed union has %d bits, expecting %d\n", node->str.c_str(), width, packed_width);
382 }
383 }
384 }
385 else {
386 offset += width;
387 }
388 }
389 return (is_union ? packed_width : offset);
390 }
391
392 [[noreturn]] static void struct_op_error(AstNode *node)
393 {
394 log_file_error(node->filename, node->location.first_line, "Unsupported operation for struct/union member %s\n", node->str.c_str()+1);
395 }
396
397 static AstNode *node_int(int ival)
398 {
399 return AstNode::mkconst_int(ival, true);
400 }
401
402 static AstNode *multiply_by_const(AstNode *expr_node, int stride)
403 {
404 return new AstNode(AST_MUL, expr_node, node_int(stride));
405 }
406
407 static AstNode *offset_indexed_range(int offset, int stride, AstNode *left_expr, AstNode *right_expr)
408 {
409 // adjust the range expressions to add an offset into the struct
410 // and maybe index using an array stride
411 auto left = left_expr->clone();
412 auto right = right_expr->clone();
413 if (stride > 1) {
414 // newleft = (left + 1) * stride - 1
415 left = new AstNode(AST_SUB, multiply_by_const(new AstNode(AST_ADD, left, node_int(1)), stride), node_int(1));
416 // newright = right * stride
417 right = multiply_by_const(right, stride);
418 }
419 // add the offset
420 if (offset) {
421 left = new AstNode(AST_ADD, node_int(offset), left);
422 right = new AstNode(AST_ADD, node_int(offset), right);
423 }
424 return new AstNode(AST_RANGE, left, right);
425 }
426
427 static AstNode *make_struct_index_range(AstNode *node, AstNode *rnode, int stride, int offset)
428 {
429 // generate a range node to perform either bit or array indexing
430 if (rnode->children.size() == 1) {
431 // index e.g. s.a[i]
432 return offset_indexed_range(offset, stride, rnode->children[0], rnode->children[0]);
433 }
434 else if (rnode->children.size() == 2) {
435 // slice e.g. s.a[i:j]
436 return offset_indexed_range(offset, stride, rnode->children[0], rnode->children[1]);
437 }
438 else {
439 struct_op_error(node);
440 }
441 }
442
443 static AstNode *slice_range(AstNode *rnode, AstNode *snode)
444 {
445 // apply the bit slice indicated by snode to the range rnode
446 log_assert(rnode->type==AST_RANGE);
447 auto left = rnode->children[0];
448 auto right = rnode->children[1];
449 log_assert(snode->type==AST_RANGE);
450 auto slice_left = snode->children[0];
451 auto slice_right = snode->children[1];
452 auto width = new AstNode(AST_SUB, slice_left->clone(), slice_right->clone());
453 right = new AstNode(AST_ADD, right->clone(), slice_right->clone());
454 left = new AstNode(AST_ADD, right->clone(), width);
455 return new AstNode(AST_RANGE, left, right);
456 }
457
458
459 AstNode *AST::make_struct_member_range(AstNode *node, AstNode *member_node)
460 {
461 // Work out the range in the packed array that corresponds to a struct member
462 // taking into account any range operations applicable to the current node
463 // such as array indexing or slicing
464 int range_left = member_node->range_left;
465 int range_right = member_node->range_right;
466 if (node->children.empty()) {
467 // no range operations apply, return the whole width
468 return make_range(range_left, range_right);
469 }
470 int stride = get_struct_array_width(member_node);
471 if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
472 // bit or array indexing e.g. s.a[2] or s.a[1:0]
473 return make_struct_index_range(node, node->children[0], stride, range_right);
474 }
475 else if (node->children.size() == 1 && node->children[0]->type == AST_MULTIRANGE) {
476 // multirange, i.e. bit slice after array index, e.g. s.a[i][p:q]
477 log_assert(stride > 1);
478 auto mrnode = node->children[0];
479 auto element_range = make_struct_index_range(node, mrnode->children[0], stride, range_right);
480 // then apply bit slice range
481 auto range = slice_range(element_range, mrnode->children[1]);
482 delete element_range;
483 return range;
484 }
485 else {
486 struct_op_error(node);
487 }
488 }
489
490 static void add_members_to_scope(AstNode *snode, std::string name)
491 {
492 // add all the members in a struct or union to local scope
493 // in case later referenced in assignments
494 log_assert(snode->type==AST_STRUCT || snode->type==AST_UNION);
495 for (auto *node : snode->children) {
496 if (node->type != AST_STRUCT_ITEM) {
497 // embedded struct or union
498 add_members_to_scope(node, name + "." + node->str);
499 }
500 else {
501 auto member_name = name + "." + node->str;
502 current_scope[member_name] = node;
503 }
504 }
505 }
506
507 static int get_max_offset(AstNode *node)
508 {
509 // get the width from the MS member in the struct
510 // as members are laid out from left to right in the packed wire
511 log_assert(node->type==AST_STRUCT || node->type==AST_UNION);
512 while (node->type != AST_STRUCT_ITEM) {
513 node = node->children[0];
514 }
515 return node->range_left;
516 }
517
518 static AstNode *make_packed_struct(AstNode *template_node, std::string &name)
519 {
520 // create a wire for the packed struct
521 auto wnode = new AstNode(AST_WIRE);
522 wnode->str = name;
523 wnode->is_logic = true;
524 wnode->range_valid = true;
525 wnode->is_signed = template_node->is_signed;
526 int offset = get_max_offset(template_node);
527 auto range = make_range(offset, 0);
528 wnode->children.push_back(range);
529 // make sure this node is the one in scope for this name
530 current_scope[name] = wnode;
531 // add all the struct members to scope under the wire's name
532 add_members_to_scope(template_node, name);
533 return wnode;
534 }
535
536 // check if a node or its children contains an assignment to the given variable
537 static bool node_contains_assignment_to(const AstNode* node, const AstNode* var)
538 {
539 if (node->type == AST_ASSIGN_EQ || node->type == AST_ASSIGN_LE) {
540 // current node is iteslf an assignment
541 log_assert(node->children.size() >= 2);
542 const AstNode* lhs = node->children[0];
543 if (lhs->type == AST_IDENTIFIER && lhs->str == var->str)
544 return false;
545 }
546 for (const AstNode* child : node->children) {
547 // if this child shadows the given variable
548 if (child != var && child->str == var->str && child->type == AST_WIRE)
549 break; // skip the remainder of this block/scope
550 // depth-first short circuit
551 if (!node_contains_assignment_to(child, var))
552 return false;
553 }
554 return true;
555 }
556
557 static std::string prefix_id(const std::string &prefix, const std::string &str)
558 {
559 log_assert(!prefix.empty() && (prefix.front() == '$' || prefix.front() == '\\'));
560 log_assert(!str.empty() && (str.front() == '$' || str.front() == '\\'));
561 log_assert(prefix.back() == '.');
562 if (str.front() == '\\')
563 return prefix + str.substr(1);
564 return prefix + str;
565 }
566
567 // convert the AST into a simpler AST that has all parameters substituted by their
568 // values, unrolled for-loops, expanded generate blocks, etc. when this function
569 // is done with an AST it can be converted into RTLIL using genRTLIL().
570 //
571 // this function also does all name resolving and sets the id2ast member of all
572 // nodes that link to a different node using names and lexical scoping.
573 bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param)
574 {
575 static int recursion_counter = 0;
576 static bool deep_recursion_warning = false;
577
578 if (recursion_counter++ == 1000 && deep_recursion_warning) {
579 log_warning("Deep recursion in AST simplifier.\nDoes this design contain overly long or deeply nested expressions, or excessive recursion?\n");
580 deep_recursion_warning = false;
581 }
582
583 static bool unevaluated_tern_branch = false;
584
585 AstNode *newNode = NULL;
586 bool did_something = false;
587
588 #if 0
589 log("-------------\n");
590 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);
591 log("const_fold=%d, at_zero=%d, in_lvalue=%d, stage=%d, width_hint=%d, sign_hint=%d, in_param=%d\n",
592 int(const_fold), int(at_zero), int(in_lvalue), int(stage), int(width_hint), int(sign_hint), int(in_param));
593 // dumpAst(NULL, "> ");
594 #endif
595
596 if (stage == 0)
597 {
598 log_assert(type == AST_MODULE || type == AST_INTERFACE);
599
600 deep_recursion_warning = true;
601 while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint, in_param)) { }
602
603 if (!flag_nomem2reg && !get_bool_attribute(ID::nomem2reg))
604 {
605 dict<AstNode*, pool<std::string>> mem2reg_places;
606 dict<AstNode*, uint32_t> mem2reg_candidates, dummy_proc_flags;
607 uint32_t flags = flag_mem2reg ? AstNode::MEM2REG_FL_ALL : 0;
608 mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, dummy_proc_flags, flags);
609
610 pool<AstNode*> mem2reg_set;
611 for (auto &it : mem2reg_candidates)
612 {
613 AstNode *mem = it.first;
614 uint32_t memflags = it.second;
615 bool this_nomeminit = flag_nomeminit;
616 log_assert((memflags & ~0x00ffff00) == 0);
617
618 if (mem->get_bool_attribute(ID::nomem2reg))
619 continue;
620
621 if (mem->get_bool_attribute(ID::nomeminit) || get_bool_attribute(ID::nomeminit))
622 this_nomeminit = true;
623
624 if (memflags & AstNode::MEM2REG_FL_FORCED)
625 goto silent_activate;
626
627 if (memflags & AstNode::MEM2REG_FL_EQ2)
628 goto verbose_activate;
629
630 if (memflags & AstNode::MEM2REG_FL_SET_ASYNC)
631 goto verbose_activate;
632
633 if ((memflags & AstNode::MEM2REG_FL_SET_INIT) && (memflags & AstNode::MEM2REG_FL_SET_ELSE) && this_nomeminit)
634 goto verbose_activate;
635
636 if (memflags & AstNode::MEM2REG_FL_CMPLX_LHS)
637 goto verbose_activate;
638
639 if ((memflags & AstNode::MEM2REG_FL_CONST_LHS) && !(memflags & AstNode::MEM2REG_FL_VAR_LHS))
640 goto verbose_activate;
641
642 // log("Note: Not replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
643 continue;
644
645 verbose_activate:
646 if (mem2reg_set.count(mem) == 0) {
647 std::string message = stringf("Replacing memory %s with list of registers.", mem->str.c_str());
648 bool first_element = true;
649 for (auto &place : mem2reg_places[it.first]) {
650 message += stringf("%s%s", first_element ? " See " : ", ", place.c_str());
651 first_element = false;
652 }
653 log_warning("%s\n", message.c_str());
654 }
655
656 silent_activate:
657 // log("Note: Replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
658 mem2reg_set.insert(mem);
659 }
660
661 for (auto node : mem2reg_set)
662 {
663 int mem_width, mem_size, addr_bits;
664 node->meminfo(mem_width, mem_size, addr_bits);
665
666 int data_range_left = node->children[0]->range_left;
667 int data_range_right = node->children[0]->range_right;
668
669 if (node->children[0]->range_swapped)
670 std::swap(data_range_left, data_range_right);
671
672 for (int i = 0; i < mem_size; i++) {
673 AstNode *reg = new AstNode(AST_WIRE, new AstNode(AST_RANGE,
674 mkconst_int(data_range_left, true), mkconst_int(data_range_right, true)));
675 reg->str = stringf("%s[%d]", node->str.c_str(), i);
676 reg->is_reg = true;
677 reg->is_signed = node->is_signed;
678 for (auto &it : node->attributes)
679 if (it.first != ID::mem2reg)
680 reg->attributes.emplace(it.first, it.second->clone());
681 reg->filename = node->filename;
682 reg->location = node->location;
683 children.push_back(reg);
684 while (reg->simplify(true, false, false, 1, -1, false, false)) { }
685 }
686 }
687
688 AstNode *async_block = NULL;
689 while (mem2reg_as_needed_pass2(mem2reg_set, this, NULL, async_block)) { }
690
691 vector<AstNode*> delnodes;
692 mem2reg_remove(mem2reg_set, delnodes);
693
694 for (auto node : delnodes)
695 delete node;
696 }
697
698 while (simplify(const_fold, at_zero, in_lvalue, 2, width_hint, sign_hint, in_param)) { }
699 recursion_counter--;
700 return false;
701 }
702
703 current_filename = filename;
704
705 // we do not look inside a task or function
706 // (but as soon as a task or function is instantiated we process the generated AST as usual)
707 if (type == AST_FUNCTION || type == AST_TASK) {
708 recursion_counter--;
709 return false;
710 }
711
712 // deactivate all calls to non-synthesis system tasks
713 // note that $display, $finish, and $stop are used for synthesis-time DRC so they're not in this list
714 if ((type == AST_FCALL || type == AST_TCALL) && (str == "$strobe" || str == "$monitor" || str == "$time" ||
715 str == "$dumpfile" || str == "$dumpvars" || str == "$dumpon" || str == "$dumpoff" || str == "$dumpall")) {
716 log_file_warning(filename, location.first_line, "Ignoring call to system %s %s.\n", type == AST_FCALL ? "function" : "task", str.c_str());
717 delete_children();
718 str = std::string();
719 }
720
721 if ((type == AST_TCALL) && (str == "$display" || str == "$write") && (!current_always || current_always->type != AST_INITIAL)) {
722 log_file_warning(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str());
723 delete_children();
724 str = std::string();
725 }
726
727 // print messages if this a call to $display() or $write()
728 // This code implements only a small subset of Verilog-2005 $display() format specifiers,
729 // but should be good enough for most uses
730 if ((type == AST_TCALL) && ((str == "$display") || (str == "$write")))
731 {
732 int nargs = GetSize(children);
733 if (nargs < 1)
734 log_file_error(filename, location.first_line, "System task `%s' got %d arguments, expected >= 1.\n",
735 str.c_str(), int(children.size()));
736
737 // First argument is the format string
738 AstNode *node_string = children[0];
739 while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
740 if (node_string->type != AST_CONSTANT)
741 log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str());
742 std::string sformat = node_string->bitsAsConst().decode_string();
743 std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint);
744 // Finally, print the message (only include a \n for $display, not for $write)
745 log("%s", sout.c_str());
746 if (str == "$display")
747 log("\n");
748 delete_children();
749 str = std::string();
750 }
751
752 // activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
753 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)
754 const_fold = true;
755 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))
756 const_fold = true;
757
758 // in certain cases a function must be evaluated constant. this is what in_param controls.
759 if (type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_PREFIX)
760 in_param = true;
761
762 std::map<std::string, AstNode*> backup_scope;
763
764 // create name resolution entries for all objects with names
765 // also merge multiple declarations for the same wire (e.g. "output foobar; reg foobar;")
766 if (type == AST_MODULE) {
767 current_scope.clear();
768 std::set<std::string> existing;
769 int counter = 0;
770 label_genblks(existing, counter);
771 std::map<std::string, AstNode*> this_wire_scope;
772 for (size_t i = 0; i < children.size(); i++) {
773 AstNode *node = children[i];
774
775 if (node->type == AST_WIRE) {
776 if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
777 for (auto c : node->children[0]->children) {
778 if (!c->is_simple_const_expr()) {
779 if (attributes.count(ID::dynports))
780 delete attributes.at(ID::dynports);
781 attributes[ID::dynports] = AstNode::mkconst_int(1, true);
782 }
783 }
784 }
785 if (this_wire_scope.count(node->str) > 0) {
786 AstNode *first_node = this_wire_scope[node->str];
787 if (first_node->is_input && node->is_reg)
788 goto wires_are_incompatible;
789 if (!node->is_input && !node->is_output && node->is_reg && node->children.size() == 0)
790 goto wires_are_compatible;
791 if (first_node->children.size() == 0 && node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
792 AstNode *r = node->children[0];
793 if (r->range_valid && r->range_left == 0 && r->range_right == 0) {
794 delete r;
795 node->children.pop_back();
796 }
797 }
798 if (first_node->children.size() != node->children.size())
799 goto wires_are_incompatible;
800 for (size_t j = 0; j < node->children.size(); j++) {
801 AstNode *n1 = first_node->children[j], *n2 = node->children[j];
802 if (n1->type == AST_RANGE && n2->type == AST_RANGE && n1->range_valid && n2->range_valid) {
803 if (n1->range_left != n2->range_left)
804 goto wires_are_incompatible;
805 if (n1->range_right != n2->range_right)
806 goto wires_are_incompatible;
807 } else if (*n1 != *n2)
808 goto wires_are_incompatible;
809 }
810 if (first_node->range_left != node->range_left)
811 goto wires_are_incompatible;
812 if (first_node->range_right != node->range_right)
813 goto wires_are_incompatible;
814 if (first_node->port_id == 0 && (node->is_input || node->is_output))
815 goto wires_are_incompatible;
816 wires_are_compatible:
817 if (node->is_input)
818 first_node->is_input = true;
819 if (node->is_output)
820 first_node->is_output = true;
821 if (node->is_reg)
822 first_node->is_reg = true;
823 if (node->is_logic)
824 first_node->is_logic = true;
825 if (node->is_signed)
826 first_node->is_signed = true;
827 for (auto &it : node->attributes) {
828 if (first_node->attributes.count(it.first) > 0)
829 delete first_node->attributes[it.first];
830 first_node->attributes[it.first] = it.second->clone();
831 }
832 children.erase(children.begin()+(i--));
833 did_something = true;
834 delete node;
835 continue;
836 wires_are_incompatible:
837 if (stage > 1)
838 log_file_error(filename, location.first_line, "Incompatible re-declaration of wire %s.\n", node->str.c_str());
839 continue;
840 }
841 this_wire_scope[node->str] = node;
842 }
843 // these nodes appear at the top level in a module and can define names
844 if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
845 node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL ||
846 node->type == AST_TYPEDEF) {
847 backup_scope[node->str] = current_scope[node->str];
848 current_scope[node->str] = node;
849 }
850 if (node->type == AST_ENUM) {
851 current_scope[node->str] = node;
852 for (auto enode : node->children) {
853 log_assert(enode->type==AST_ENUM_ITEM);
854 if (current_scope.count(enode->str) == 0)
855 current_scope[enode->str] = enode;
856 else
857 log_file_error(filename, location.first_line, "enum item %s already exists\n", enode->str.c_str());
858 }
859 }
860 }
861 for (size_t i = 0; i < children.size(); i++) {
862 AstNode *node = children[i];
863 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)
864 while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM))
865 did_something = true;
866 if (node->type == AST_ENUM) {
867 for (auto enode : node->children){
868 log_assert(enode->type==AST_ENUM_ITEM);
869 while (node->simplify(true, false, false, 1, -1, false, in_param))
870 did_something = true;
871 }
872 }
873 }
874 }
875
876 // create name resolution entries for all objects with names
877 if (type == AST_PACKAGE) {
878 //add names to package scope
879 for (size_t i = 0; i < children.size(); i++) {
880 AstNode *node = children[i];
881 // these nodes appear at the top level in a package and can define names
882 if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_TYPEDEF || node->type == AST_FUNCTION || node->type == AST_TASK) {
883 current_scope[node->str] = node;
884 }
885 if (node->type == AST_ENUM) {
886 current_scope[node->str] = node;
887 for (auto enode : node->children) {
888 log_assert(enode->type==AST_ENUM_ITEM);
889 if (current_scope.count(enode->str) == 0)
890 current_scope[enode->str] = enode;
891 else
892 log_file_error(filename, location.first_line, "enum item %s already exists in package\n", enode->str.c_str());
893 }
894 }
895 }
896 }
897
898
899 auto backup_current_block = current_block;
900 auto backup_current_block_child = current_block_child;
901 auto backup_current_top_block = current_top_block;
902 auto backup_current_always = current_always;
903 auto backup_current_always_clocked = current_always_clocked;
904
905 if (type == AST_ALWAYS || type == AST_INITIAL)
906 {
907 if (current_always != nullptr)
908 log_file_error(filename, location.first_line, "Invalid nesting of always blocks and/or initializations.\n");
909
910 current_always = this;
911 current_always_clocked = false;
912
913 if (type == AST_ALWAYS)
914 for (auto child : children) {
915 if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE)
916 current_always_clocked = true;
917 if (child->type == AST_EDGE && GetSize(child->children) == 1 &&
918 child->children[0]->type == AST_IDENTIFIER && child->children[0]->str == "\\$global_clock")
919 current_always_clocked = true;
920 }
921 }
922
923 if (type == AST_ARGUMENT)
924 {
925 if (children.size() == 1 && children[0]->type == AST_CONSTANT)
926 {
927 // HACK: For port bindings using unbased unsized literals, mark them
928 // signed so they sign-extend. The hierarchy will still incorrectly
929 // generate a warning complaining about resizing the expression.
930 // This also doesn't handle the complex of something like a ternary
931 // expression bound to a port, where the actual size of the port is
932 // needed to resolve the expression correctly.
933 AstNode *arg = children[0];
934 if (arg->is_unsized)
935 arg->is_signed = true;
936 }
937 }
938
939 int backup_width_hint = width_hint;
940 bool backup_sign_hint = sign_hint;
941
942 bool detect_width_simple = false;
943 bool child_0_is_self_determined = false;
944 bool child_1_is_self_determined = false;
945 bool child_2_is_self_determined = false;
946 bool children_are_self_determined = false;
947 bool reset_width_after_children = false;
948
949 switch (type)
950 {
951 case AST_ASSIGN_EQ:
952 case AST_ASSIGN_LE:
953 case AST_ASSIGN:
954 while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, in_param) == true)
955 did_something = true;
956 while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, in_param) == true)
957 did_something = true;
958 children[0]->detectSignWidth(backup_width_hint, backup_sign_hint);
959 children[1]->detectSignWidth(width_hint, sign_hint);
960 width_hint = max(width_hint, backup_width_hint);
961 child_0_is_self_determined = true;
962 // test only once, before optimizations and memory mappings but after assignment LHS was mapped to an identifier
963 if (children[0]->id2ast && !children[0]->was_checked) {
964 if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && children[0]->id2ast->is_logic)
965 children[0]->id2ast->is_reg = true; // if logic type is used in a block asignment
966 if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && !children[0]->id2ast->is_reg)
967 log_warning("wire '%s' is assigned in a block at %s.\n", children[0]->str.c_str(), loc_string().c_str());
968 if (type == AST_ASSIGN && children[0]->id2ast->is_reg) {
969 bool is_rand_reg = false;
970 if (children[1]->type == AST_FCALL) {
971 if (children[1]->str == "\\$anyconst")
972 is_rand_reg = true;
973 if (children[1]->str == "\\$anyseq")
974 is_rand_reg = true;
975 if (children[1]->str == "\\$allconst")
976 is_rand_reg = true;
977 if (children[1]->str == "\\$allseq")
978 is_rand_reg = true;
979 }
980 if (!is_rand_reg)
981 log_warning("reg '%s' is assigned in a continuous assignment at %s.\n", children[0]->str.c_str(), loc_string().c_str());
982 }
983 children[0]->was_checked = true;
984 }
985 break;
986
987 case AST_STRUCT:
988 case AST_UNION:
989 if (!basic_prep) {
990 for (auto *node : children) {
991 // resolve any ranges
992 while (!node->basic_prep && node->simplify(true, false, false, stage, -1, false, false)) {
993 did_something = true;
994 }
995 }
996 // determine member offsets and widths
997 size_packed_struct(this, 0);
998
999 // instance rather than just a type in a typedef or outer struct?
1000 if (!str.empty() && str[0] == '\\') {
1001 // instance so add a wire for the packed structure
1002 auto wnode = make_packed_struct(this, str);
1003 log_assert(current_ast_mod);
1004 current_ast_mod->children.push_back(wnode);
1005 }
1006 basic_prep = true;
1007 }
1008 break;
1009
1010 case AST_STRUCT_ITEM:
1011 break;
1012
1013 case AST_ENUM:
1014 //log("\nENUM %s: %d child %d\n", str.c_str(), basic_prep, children[0]->basic_prep);
1015 if (!basic_prep) {
1016 for (auto item_node : children) {
1017 while (!item_node->basic_prep && item_node->simplify(false, false, false, stage, -1, false, in_param))
1018 did_something = true;
1019 }
1020 // allocate values (called more than once)
1021 allocateDefaultEnumValues();
1022 }
1023 break;
1024
1025 case AST_PARAMETER:
1026 case AST_LOCALPARAM:
1027 while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true)
1028 did_something = true;
1029 children[0]->detectSignWidth(width_hint, sign_hint);
1030 if (children.size() > 1 && children[1]->type == AST_RANGE) {
1031 while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true)
1032 did_something = true;
1033 if (!children[1]->range_valid)
1034 log_file_error(filename, location.first_line, "Non-constant width range on parameter decl.\n");
1035 width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1);
1036 }
1037 break;
1038 case AST_ENUM_ITEM:
1039 while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, in_param))
1040 did_something = true;
1041 children[0]->detectSignWidth(width_hint, sign_hint);
1042 if (children.size() > 1 && children[1]->type == AST_RANGE) {
1043 while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, in_param))
1044 did_something = true;
1045 if (!children[1]->range_valid)
1046 log_file_error(filename, location.first_line, "Non-constant width range on enum item decl.\n");
1047 width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1);
1048 }
1049 break;
1050
1051 case AST_TO_BITS:
1052 case AST_TO_SIGNED:
1053 case AST_TO_UNSIGNED:
1054 case AST_SELFSZ:
1055 case AST_CAST_SIZE:
1056 case AST_CONCAT:
1057 case AST_REPLICATE:
1058 case AST_REDUCE_AND:
1059 case AST_REDUCE_OR:
1060 case AST_REDUCE_XOR:
1061 case AST_REDUCE_XNOR:
1062 case AST_REDUCE_BOOL:
1063 detect_width_simple = true;
1064 children_are_self_determined = true;
1065 break;
1066
1067 case AST_NEG:
1068 case AST_BIT_NOT:
1069 case AST_POS:
1070 case AST_BIT_AND:
1071 case AST_BIT_OR:
1072 case AST_BIT_XOR:
1073 case AST_BIT_XNOR:
1074 case AST_ADD:
1075 case AST_SUB:
1076 case AST_MUL:
1077 case AST_DIV:
1078 case AST_MOD:
1079 detect_width_simple = true;
1080 break;
1081
1082 case AST_SHIFT_LEFT:
1083 case AST_SHIFT_RIGHT:
1084 case AST_SHIFT_SLEFT:
1085 case AST_SHIFT_SRIGHT:
1086 case AST_POW:
1087 detect_width_simple = true;
1088 child_1_is_self_determined = true;
1089 break;
1090
1091 case AST_LT:
1092 case AST_LE:
1093 case AST_EQ:
1094 case AST_NE:
1095 case AST_EQX:
1096 case AST_NEX:
1097 case AST_GE:
1098 case AST_GT:
1099 width_hint = -1;
1100 sign_hint = true;
1101 for (auto child : children) {
1102 while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true)
1103 did_something = true;
1104 child->detectSignWidthWorker(width_hint, sign_hint);
1105 }
1106 reset_width_after_children = true;
1107 break;
1108
1109 case AST_LOGIC_AND:
1110 case AST_LOGIC_OR:
1111 case AST_LOGIC_NOT:
1112 detect_width_simple = true;
1113 children_are_self_determined = true;
1114 break;
1115
1116 case AST_TERNARY:
1117 child_0_is_self_determined = true;
1118 break;
1119
1120 case AST_MEMRD:
1121 detect_width_simple = true;
1122 children_are_self_determined = true;
1123 break;
1124
1125 case AST_FCALL:
1126 case AST_TCALL:
1127 children_are_self_determined = true;
1128 break;
1129
1130 default:
1131 width_hint = -1;
1132 sign_hint = false;
1133 }
1134
1135 if (detect_width_simple && width_hint < 0) {
1136 if (type == AST_REPLICATE)
1137 while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, true) == true)
1138 did_something = true;
1139 for (auto child : children)
1140 while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true)
1141 did_something = true;
1142 detectSignWidth(width_hint, sign_hint);
1143 }
1144
1145 if (type == AST_FCALL && str == "\\$past")
1146 detectSignWidth(width_hint, sign_hint);
1147
1148 if (type == AST_TERNARY) {
1149 if (width_hint < 0) {
1150 while (!children[0]->basic_prep && children[0]->simplify(true, false, in_lvalue, stage, -1, false, in_param))
1151 did_something = true;
1152
1153 bool backup_unevaluated_tern_branch = unevaluated_tern_branch;
1154 AstNode *chosen = get_tern_choice().first;
1155
1156 unevaluated_tern_branch = backup_unevaluated_tern_branch || chosen == children[2];
1157 while (!children[1]->basic_prep && children[1]->simplify(false, false, in_lvalue, stage, -1, false, in_param))
1158 did_something = true;
1159
1160 unevaluated_tern_branch = backup_unevaluated_tern_branch || chosen == children[1];
1161 while (!children[2]->basic_prep && children[2]->simplify(false, false, in_lvalue, stage, -1, false, in_param))
1162 did_something = true;
1163
1164 unevaluated_tern_branch = backup_unevaluated_tern_branch;
1165 detectSignWidth(width_hint, sign_hint);
1166 }
1167 int width_hint_left, width_hint_right;
1168 bool sign_hint_left, sign_hint_right;
1169 bool found_real_left, found_real_right;
1170 children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left);
1171 children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right);
1172 if (found_real_left || found_real_right) {
1173 child_1_is_self_determined = true;
1174 child_2_is_self_determined = true;
1175 }
1176 }
1177
1178 if (type == AST_CONDX && children.size() > 0 && children.at(0)->type == AST_CONSTANT) {
1179 for (auto &bit : children.at(0)->bits)
1180 if (bit == State::Sz || bit == State::Sx)
1181 bit = State::Sa;
1182 }
1183
1184 if (type == AST_CONDZ && children.size() > 0 && children.at(0)->type == AST_CONSTANT) {
1185 for (auto &bit : children.at(0)->bits)
1186 if (bit == State::Sz)
1187 bit = State::Sa;
1188 }
1189
1190 if (const_fold && type == AST_CASE)
1191 {
1192 int width_hint;
1193 bool sign_hint;
1194 detectSignWidth(width_hint, sign_hint);
1195 while (children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { }
1196 if (children[0]->type == AST_CONSTANT && children[0]->bits_only_01()) {
1197 RTLIL::Const case_expr = children[0]->bitsAsConst(width_hint, sign_hint);
1198 std::vector<AstNode*> new_children;
1199 new_children.push_back(children[0]);
1200 for (int i = 1; i < GetSize(children); i++) {
1201 AstNode *child = children[i];
1202 log_assert(child->type == AST_COND || child->type == AST_CONDX || child->type == AST_CONDZ);
1203 for (auto v : child->children) {
1204 if (v->type == AST_DEFAULT)
1205 goto keep_const_cond;
1206 if (v->type == AST_BLOCK)
1207 continue;
1208 while (v->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { }
1209 if (v->type == AST_CONSTANT && v->bits_only_01()) {
1210 RTLIL::Const case_item_expr = v->bitsAsConst(width_hint, sign_hint);
1211 RTLIL::Const match = const_eq(case_expr, case_item_expr, sign_hint, sign_hint, 1);
1212 log_assert(match.bits.size() == 1);
1213 if (match.bits.front() == RTLIL::State::S1) {
1214 while (i+1 < GetSize(children))
1215 delete children[++i];
1216 goto keep_const_cond;
1217 }
1218 continue;
1219 }
1220 goto keep_const_cond;
1221 }
1222 if (0)
1223 keep_const_cond:
1224 new_children.push_back(child);
1225 else
1226 delete child;
1227 }
1228 new_children.swap(children);
1229 }
1230 }
1231
1232 dict<std::string, pool<int>> backup_memwr_visible;
1233 dict<std::string, pool<int>> final_memwr_visible;
1234
1235 if (type == AST_CASE && stage == 2) {
1236 backup_memwr_visible = current_memwr_visible;
1237 final_memwr_visible = current_memwr_visible;
1238 }
1239
1240 // simplify all children first
1241 // (iterate by index as e.g. auto wires can add new children in the process)
1242 for (size_t i = 0; i < children.size(); i++) {
1243 bool did_something_here = true;
1244 bool backup_flag_autowire = flag_autowire;
1245 bool backup_unevaluated_tern_branch = unevaluated_tern_branch;
1246 if ((type == AST_GENFOR || type == AST_FOR) && i >= 3)
1247 break;
1248 if ((type == AST_GENIF || type == AST_GENCASE) && i >= 1)
1249 break;
1250 if (type == AST_GENBLOCK)
1251 break;
1252 if (type == AST_BLOCK && !str.empty())
1253 break;
1254 if (type == AST_PREFIX && i >= 1)
1255 break;
1256 if (type == AST_DEFPARAM && i == 0)
1257 flag_autowire = true;
1258 if (type == AST_TERNARY && i > 0 && !unevaluated_tern_branch) {
1259 AstNode *chosen = get_tern_choice().first;
1260 unevaluated_tern_branch = chosen && chosen != children[i];
1261 }
1262 while (did_something_here && i < children.size()) {
1263 bool const_fold_here = const_fold, in_lvalue_here = in_lvalue;
1264 int width_hint_here = width_hint;
1265 bool sign_hint_here = sign_hint;
1266 bool in_param_here = in_param;
1267 if (i == 0 && (type == AST_REPLICATE || type == AST_WIRE))
1268 const_fold_here = true, in_param_here = true;
1269 if (i == 0 && (type == AST_GENIF || type == AST_GENCASE))
1270 in_param_here = true;
1271 if (i == 1 && (type == AST_FOR || type == AST_GENFOR))
1272 in_param_here = true;
1273 if (type == AST_PARAMETER || type == AST_LOCALPARAM)
1274 const_fold_here = true;
1275 if (i == 0 && (type == AST_ASSIGN || type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE))
1276 in_lvalue_here = true;
1277 if (type == AST_BLOCK) {
1278 current_block = this;
1279 current_block_child = children[i];
1280 }
1281 if ((type == AST_ALWAYS || type == AST_INITIAL) && children[i]->type == AST_BLOCK)
1282 current_top_block = children[i];
1283 if (i == 0 && child_0_is_self_determined)
1284 width_hint_here = -1, sign_hint_here = false;
1285 if (i == 1 && child_1_is_self_determined)
1286 width_hint_here = -1, sign_hint_here = false;
1287 if (i == 2 && child_2_is_self_determined)
1288 width_hint_here = -1, sign_hint_here = false;
1289 if (children_are_self_determined)
1290 width_hint_here = -1, sign_hint_here = false;
1291 did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param_here);
1292 if (did_something_here)
1293 did_something = true;
1294 }
1295 if (stage == 2 && children[i]->type == AST_INITIAL && current_ast_mod != this) {
1296 current_ast_mod->children.push_back(children[i]);
1297 children.erase(children.begin() + (i--));
1298 did_something = true;
1299 }
1300 flag_autowire = backup_flag_autowire;
1301 unevaluated_tern_branch = backup_unevaluated_tern_branch;
1302 if (stage == 2 && type == AST_CASE) {
1303 for (auto &x : current_memwr_visible) {
1304 for (int y : x.second)
1305 final_memwr_visible[x.first].insert(y);
1306 }
1307 current_memwr_visible = backup_memwr_visible;
1308 }
1309 }
1310 for (auto &attr : attributes) {
1311 while (attr.second->simplify(true, false, false, stage, -1, false, true))
1312 did_something = true;
1313 }
1314 if (type == AST_CASE && stage == 2) {
1315 current_memwr_visible = final_memwr_visible;
1316 }
1317 if (type == AST_ALWAYS && stage == 2) {
1318 current_memwr_visible.clear();
1319 current_memwr_count.clear();
1320 }
1321
1322 if (reset_width_after_children) {
1323 width_hint = backup_width_hint;
1324 sign_hint = backup_sign_hint;
1325 if (width_hint < 0)
1326 detectSignWidth(width_hint, sign_hint);
1327 }
1328
1329 current_block = backup_current_block;
1330 current_block_child = backup_current_block_child;
1331 current_top_block = backup_current_top_block;
1332 current_always = backup_current_always;
1333 current_always_clocked = backup_current_always_clocked;
1334
1335 for (auto it = backup_scope.begin(); it != backup_scope.end(); it++) {
1336 if (it->second == NULL)
1337 current_scope.erase(it->first);
1338 else
1339 current_scope[it->first] = it->second;
1340 }
1341
1342 current_filename = filename;
1343
1344 if (type == AST_MODULE)
1345 current_scope.clear();
1346
1347 // convert defparam nodes to cell parameters
1348 if (type == AST_DEFPARAM && !children.empty())
1349 {
1350 if (children[0]->type != AST_IDENTIFIER)
1351 log_file_error(filename, location.first_line, "Module name in defparam contains non-constant expressions!\n");
1352
1353 string modname, paramname = children[0]->str;
1354
1355 size_t pos = paramname.rfind('.');
1356
1357 while (pos != 0 && pos != std::string::npos)
1358 {
1359 modname = paramname.substr(0, pos);
1360
1361 if (current_scope.count(modname))
1362 break;
1363
1364 pos = paramname.rfind('.', pos - 1);
1365 }
1366
1367 if (pos == std::string::npos)
1368 log_file_error(filename, location.first_line, "Can't find object for defparam `%s`!\n", RTLIL::unescape_id(paramname).c_str());
1369
1370 paramname = "\\" + paramname.substr(pos+1);
1371
1372 if (current_scope.at(modname)->type != AST_CELL)
1373 log_file_error(filename, location.first_line, "Defparam argument `%s . %s` does not match a cell!\n",
1374 RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paramname).c_str());
1375
1376 AstNode *paraset = new AstNode(AST_PARASET, children[1]->clone(), GetSize(children) > 2 ? children[2]->clone() : NULL);
1377 paraset->str = paramname;
1378
1379 AstNode *cell = current_scope.at(modname);
1380 cell->children.insert(cell->children.begin() + 1, paraset);
1381 delete_children();
1382 }
1383
1384 // resolve typedefs
1385 if (type == AST_TYPEDEF) {
1386 log_assert(children.size() == 1);
1387 auto type_node = children[0];
1388 log_assert(type_node->type == AST_WIRE || type_node->type == AST_MEMORY || type_node->type == AST_STRUCT || type_node->type == AST_UNION);
1389 while (type_node->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {
1390 did_something = true;
1391 }
1392 log_assert(!type_node->is_custom_type);
1393 }
1394
1395 // resolve types of wires
1396 if (type == AST_WIRE || type == AST_MEMORY) {
1397 if (is_custom_type) {
1398 log_assert(children.size() >= 1);
1399 log_assert(children[0]->type == AST_WIRETYPE);
1400 auto type_name = children[0]->str;
1401 if (!current_scope.count(type_name)) {
1402 log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", type_name.c_str());
1403 }
1404 AstNode *resolved_type_node = current_scope.at(type_name);
1405 if (resolved_type_node->type != AST_TYPEDEF)
1406 log_file_error(filename, location.first_line, "`%s' does not name a type\n", type_name.c_str());
1407 log_assert(resolved_type_node->children.size() == 1);
1408 AstNode *template_node = resolved_type_node->children[0];
1409
1410 // Ensure typedef itself is fully simplified
1411 while (template_node->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
1412
1413 if (template_node->type == AST_STRUCT || template_node->type == AST_UNION) {
1414 // replace with wire representing the packed structure
1415 newNode = make_packed_struct(template_node, str);
1416 // add original input/output attribute to resolved wire
1417 newNode->is_input = this->is_input;
1418 newNode->is_output = this->is_output;
1419 current_scope[str] = this;
1420 goto apply_newNode;
1421 }
1422
1423 // Remove type reference
1424 delete children[0];
1425 children.erase(children.begin());
1426
1427 if (type == AST_WIRE)
1428 type = template_node->type;
1429 is_reg = template_node->is_reg;
1430 is_logic = template_node->is_logic;
1431 is_signed = template_node->is_signed;
1432 is_string = template_node->is_string;
1433 is_custom_type = template_node->is_custom_type;
1434
1435 range_valid = template_node->range_valid;
1436 range_swapped = template_node->range_swapped;
1437 range_left = template_node->range_left;
1438 range_right = template_node->range_right;
1439
1440 attributes[ID::wiretype] = mkconst_str(resolved_type_node->str);
1441
1442 // if an enum then add attributes to support simulator tracing
1443 annotateTypedEnums(template_node);
1444
1445 // Insert clones children from template at beginning
1446 for (int i = 0; i < GetSize(template_node->children); i++)
1447 children.insert(children.begin() + i, template_node->children[i]->clone());
1448
1449 if (type == AST_MEMORY && GetSize(children) == 1) {
1450 // Single-bit memories must have [0:0] range
1451 AstNode *rng = make_range(0, 0);
1452 children.insert(children.begin(), rng);
1453 }
1454 did_something = true;
1455 }
1456 log_assert(!is_custom_type);
1457 }
1458
1459 // resolve types of parameters
1460 if (type == AST_LOCALPARAM || type == AST_PARAMETER) {
1461 if (is_custom_type) {
1462 log_assert(children.size() == 2);
1463 log_assert(children[1]->type == AST_WIRETYPE);
1464 if (!current_scope.count(children[1]->str))
1465 log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", children[1]->str.c_str());
1466 AstNode *resolved_type_node = current_scope.at(children[1]->str);
1467 if (resolved_type_node->type != AST_TYPEDEF)
1468 log_file_error(filename, location.first_line, "`%s' does not name a type\n", children[1]->str.c_str());
1469 log_assert(resolved_type_node->children.size() == 1);
1470 AstNode *template_node = resolved_type_node->children[0];
1471 delete children[1];
1472 children.pop_back();
1473
1474 // Ensure typedef itself is fully simplified
1475 while(template_node->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
1476
1477 if (template_node->type == AST_MEMORY)
1478 log_file_error(filename, location.first_line, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str());
1479 is_signed = template_node->is_signed;
1480 is_string = template_node->is_string;
1481 is_custom_type = template_node->is_custom_type;
1482
1483 range_valid = template_node->range_valid;
1484 range_swapped = template_node->range_swapped;
1485 range_left = template_node->range_left;
1486 range_right = template_node->range_right;
1487 attributes[ID::wiretype] = mkconst_str(resolved_type_node->str);
1488 for (auto template_child : template_node->children)
1489 children.push_back(template_child->clone());
1490 did_something = true;
1491 }
1492 log_assert(!is_custom_type);
1493 }
1494
1495 // resolve constant prefixes
1496 if (type == AST_PREFIX) {
1497 if (children[0]->type != AST_CONSTANT) {
1498 // dumpAst(NULL, "> ");
1499 log_file_error(filename, location.first_line, "Index in generate block prefix syntax is not constant!\n");
1500 }
1501 if (children[1]->type == AST_PREFIX)
1502 children[1]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param);
1503 log_assert(children[1]->type == AST_IDENTIFIER);
1504 newNode = children[1]->clone();
1505 const char *second_part = children[1]->str.c_str();
1506 if (second_part[0] == '\\')
1507 second_part++;
1508 newNode->str = stringf("%s[%d].%s", str.c_str(), children[0]->integer, second_part);
1509 goto apply_newNode;
1510 }
1511
1512 // evaluate TO_BITS nodes
1513 if (type == AST_TO_BITS) {
1514 if (children[0]->type != AST_CONSTANT)
1515 log_file_error(filename, location.first_line, "Left operand of to_bits expression is not constant!\n");
1516 if (children[1]->type != AST_CONSTANT)
1517 log_file_error(filename, location.first_line, "Right operand of to_bits expression is not constant!\n");
1518 RTLIL::Const new_value = children[1]->bitsAsConst(children[0]->bitsAsConst().as_int(), children[1]->is_signed);
1519 newNode = mkconst_bits(new_value.bits, children[1]->is_signed);
1520 goto apply_newNode;
1521 }
1522
1523 // annotate constant ranges
1524 if (type == AST_RANGE) {
1525 bool old_range_valid = range_valid;
1526 range_valid = false;
1527 range_swapped = false;
1528 range_left = -1;
1529 range_right = 0;
1530 log_assert(children.size() >= 1);
1531 if (children[0]->type == AST_CONSTANT) {
1532 range_valid = true;
1533 range_left = children[0]->integer;
1534 if (children.size() == 1)
1535 range_right = range_left;
1536 }
1537 if (children.size() >= 2) {
1538 if (children[1]->type == AST_CONSTANT)
1539 range_right = children[1]->integer;
1540 else
1541 range_valid = false;
1542 }
1543 if (old_range_valid != range_valid)
1544 did_something = true;
1545 if (range_valid && range_right > range_left) {
1546 int tmp = range_right;
1547 range_right = range_left;
1548 range_left = tmp;
1549 range_swapped = true;
1550 }
1551 }
1552
1553 // annotate wires with their ranges
1554 if (type == AST_WIRE) {
1555 if (children.size() > 0) {
1556 if (children[0]->range_valid) {
1557 if (!range_valid)
1558 did_something = true;
1559 range_valid = true;
1560 range_swapped = children[0]->range_swapped;
1561 range_left = children[0]->range_left;
1562 range_right = children[0]->range_right;
1563 bool force_upto = false, force_downto = false;
1564 if (attributes.count(ID::force_upto)) {
1565 AstNode *val = attributes[ID::force_upto];
1566 if (val->type != AST_CONSTANT)
1567 log_file_error(filename, location.first_line, "Attribute `force_upto' with non-constant value!\n");
1568 force_upto = val->asAttrConst().as_bool();
1569 }
1570 if (attributes.count(ID::force_downto)) {
1571 AstNode *val = attributes[ID::force_downto];
1572 if (val->type != AST_CONSTANT)
1573 log_file_error(filename, location.first_line, "Attribute `force_downto' with non-constant value!\n");
1574 force_downto = val->asAttrConst().as_bool();
1575 }
1576 if (force_upto && force_downto)
1577 log_file_error(filename, location.first_line, "Attributes `force_downto' and `force_upto' cannot be both set!\n");
1578 if ((force_upto && !range_swapped) || (force_downto && range_swapped)) {
1579 std::swap(range_left, range_right);
1580 range_swapped = force_upto;
1581 }
1582 }
1583 } else {
1584 if (!range_valid)
1585 did_something = true;
1586 range_valid = true;
1587 range_swapped = false;
1588 range_left = 0;
1589 range_right = 0;
1590 }
1591 }
1592
1593 // resolve multiranges on memory decl
1594 if (type == AST_MEMORY && children.size() > 1 && children[1]->type == AST_MULTIRANGE)
1595 {
1596 int total_size = 1;
1597 multirange_dimensions.clear();
1598 multirange_swapped.clear();
1599 for (auto range : children[1]->children) {
1600 if (!range->range_valid)
1601 log_file_error(filename, location.first_line, "Non-constant range on memory decl.\n");
1602 multirange_dimensions.push_back(min(range->range_left, range->range_right));
1603 multirange_dimensions.push_back(max(range->range_left, range->range_right) - min(range->range_left, range->range_right) + 1);
1604 multirange_swapped.push_back(range->range_swapped);
1605 total_size *= multirange_dimensions.back();
1606 }
1607 delete children[1];
1608 children[1] = new AstNode(AST_RANGE, AstNode::mkconst_int(0, true), AstNode::mkconst_int(total_size-1, true));
1609 did_something = true;
1610 }
1611
1612 // resolve multiranges on memory access
1613 if (type == AST_IDENTIFIER && id2ast && id2ast->type == AST_MEMORY && children.size() > 0 && children[0]->type == AST_MULTIRANGE)
1614 {
1615 AstNode *index_expr = nullptr;
1616
1617 integer = children[0]->children.size(); // save original number of dimensions for $size() etc.
1618 for (int i = 0; 2*i < GetSize(id2ast->multirange_dimensions); i++)
1619 {
1620 if (GetSize(children[0]->children) <= i)
1621 log_file_error(filename, location.first_line, "Insufficient number of array indices for %s.\n", log_id(str));
1622
1623 AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone();
1624
1625 if (id2ast->multirange_dimensions[2*i])
1626 new_index_expr = new AstNode(AST_SUB, new_index_expr, AstNode::mkconst_int(id2ast->multirange_dimensions[2*i], true));
1627
1628 if (i == 0)
1629 index_expr = new_index_expr;
1630 else
1631 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);
1632 }
1633
1634 for (int i = GetSize(id2ast->multirange_dimensions)/2; i < GetSize(children[0]->children); i++)
1635 children.push_back(children[0]->children[i]->clone());
1636
1637 delete children[0];
1638 if (index_expr == nullptr)
1639 children.erase(children.begin());
1640 else
1641 children[0] = new AstNode(AST_RANGE, index_expr);
1642
1643 did_something = true;
1644 }
1645
1646 // trim/extend parameters
1647 if (type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_ENUM_ITEM) {
1648 if (children.size() > 1 && children[1]->type == AST_RANGE) {
1649 if (!children[1]->range_valid)
1650 log_file_error(filename, location.first_line, "Non-constant width range on parameter decl.\n");
1651 int width = std::abs(children[1]->range_left - children[1]->range_right) + 1;
1652 if (children[0]->type == AST_REALVALUE) {
1653 RTLIL::Const constvalue = children[0]->realAsConst(width);
1654 log_file_warning(filename, location.first_line, "converting real value %e to binary %s.\n",
1655 children[0]->realvalue, log_signal(constvalue));
1656 delete children[0];
1657 children[0] = mkconst_bits(constvalue.bits, sign_hint);
1658 did_something = true;
1659 }
1660 if (children[0]->type == AST_CONSTANT) {
1661 if (width != int(children[0]->bits.size())) {
1662 RTLIL::SigSpec sig(children[0]->bits);
1663 sig.extend_u0(width, children[0]->is_signed);
1664 AstNode *old_child_0 = children[0];
1665 children[0] = mkconst_bits(sig.as_const().bits, is_signed);
1666 delete old_child_0;
1667 }
1668 children[0]->is_signed = is_signed;
1669 }
1670 range_valid = true;
1671 range_swapped = children[1]->range_swapped;
1672 range_left = children[1]->range_left;
1673 range_right = children[1]->range_right;
1674 } else
1675 if (children.size() > 1 && children[1]->type == AST_REALVALUE && children[0]->type == AST_CONSTANT) {
1676 double as_realvalue = children[0]->asReal(sign_hint);
1677 delete children[0];
1678 children[0] = new AstNode(AST_REALVALUE);
1679 children[0]->realvalue = as_realvalue;
1680 did_something = true;
1681 }
1682 }
1683
1684 if (type == AST_IDENTIFIER && !basic_prep) {
1685 // check if a plausible struct member sss.mmmm
1686 std::string sname;
1687 if (name_has_dot(str, sname)) {
1688 if (current_scope.count(str) > 0) {
1689 auto item_node = current_scope[str];
1690 if (item_node->type == AST_STRUCT_ITEM) {
1691 // structure member, rewrite this node to reference the packed struct wire
1692 auto range = make_struct_member_range(this, item_node);
1693 newNode = new AstNode(AST_IDENTIFIER, range);
1694 newNode->str = sname;
1695 newNode->basic_prep = true;
1696 if (item_node->is_signed)
1697 newNode = new AstNode(AST_TO_SIGNED, newNode);
1698 goto apply_newNode;
1699 }
1700 }
1701 }
1702 }
1703 // annotate identifiers using scope resolution and create auto-wires as needed
1704 if (type == AST_IDENTIFIER) {
1705 if (current_scope.count(str) == 0) {
1706 AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod;
1707 str = try_pop_module_prefix();
1708 for (auto node : current_scope_ast->children) {
1709 //log("looking at mod scope child %s\n", type2str(node->type).c_str());
1710 switch (node->type) {
1711 case AST_PARAMETER:
1712 case AST_LOCALPARAM:
1713 case AST_WIRE:
1714 case AST_AUTOWIRE:
1715 case AST_GENVAR:
1716 case AST_MEMORY:
1717 case AST_FUNCTION:
1718 case AST_TASK:
1719 case AST_DPI_FUNCTION:
1720 //log("found child %s, %s\n", type2str(node->type).c_str(), node->str.c_str());
1721 if (str == node->str) {
1722 //log("add %s, type %s to scope\n", str.c_str(), type2str(node->type).c_str());
1723 current_scope[node->str] = node;
1724 }
1725 break;
1726 case AST_ENUM:
1727 current_scope[node->str] = node;
1728 for (auto enum_node : node->children) {
1729 log_assert(enum_node->type==AST_ENUM_ITEM);
1730 if (str == enum_node->str) {
1731 //log("\nadding enum item %s to scope\n", str.c_str());
1732 current_scope[str] = enum_node;
1733 }
1734 }
1735 break;
1736 default:
1737 break;
1738 }
1739 }
1740 }
1741 if (current_scope.count(str) == 0) {
1742 if (current_ast_mod == nullptr) {
1743 log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared outside of a module.\n", str.c_str());
1744 } else if (flag_autowire || str == "\\$global_clock") {
1745 AstNode *auto_wire = new AstNode(AST_AUTOWIRE);
1746 auto_wire->str = str;
1747 current_ast_mod->children.push_back(auto_wire);
1748 current_scope[str] = auto_wire;
1749 did_something = true;
1750 } else {
1751 log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str());
1752 }
1753 }
1754 if (id2ast != current_scope[str]) {
1755 id2ast = current_scope[str];
1756 did_something = true;
1757 }
1758 }
1759
1760 // split memory access with bit select to individual statements
1761 if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE && !in_lvalue && stage == 2)
1762 {
1763 if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1)
1764 log_file_error(filename, location.first_line, "Invalid bit-select on memory access!\n");
1765
1766 int mem_width, mem_size, addr_bits;
1767 id2ast->meminfo(mem_width, mem_size, addr_bits);
1768
1769 int data_range_left = id2ast->children[0]->range_left;
1770 int data_range_right = id2ast->children[0]->range_right;
1771
1772 if (id2ast->children[0]->range_swapped)
1773 std::swap(data_range_left, data_range_right);
1774
1775 std::stringstream sstr;
1776 sstr << "$mem2bits$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
1777 std::string wire_id = sstr.str();
1778
1779 AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(data_range_left, true), mkconst_int(data_range_right, true)));
1780 wire->str = wire_id;
1781 if (current_block)
1782 wire->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
1783 current_ast_mod->children.push_back(wire);
1784 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
1785
1786 AstNode *data = clone();
1787 delete data->children[1];
1788 data->children.pop_back();
1789
1790 AstNode *assign = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), data);
1791 assign->children[0]->str = wire_id;
1792 assign->children[0]->was_checked = true;
1793
1794 if (current_block)
1795 {
1796 size_t assign_idx = 0;
1797 while (assign_idx < current_block->children.size() && current_block->children[assign_idx] != current_block_child)
1798 assign_idx++;
1799 log_assert(assign_idx < current_block->children.size());
1800 current_block->children.insert(current_block->children.begin()+assign_idx, assign);
1801 wire->is_reg = true;
1802 }
1803 else
1804 {
1805 AstNode *proc = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
1806 proc->children[0]->children.push_back(assign);
1807 current_ast_mod->children.push_back(proc);
1808 }
1809
1810 newNode = new AstNode(AST_IDENTIFIER, children[1]->clone());
1811 newNode->str = wire_id;
1812 newNode->integer = integer; // save original number of dimensions for $size() etc.
1813 newNode->id2ast = wire;
1814 goto apply_newNode;
1815 }
1816
1817 if (type == AST_WHILE)
1818 log_file_error(filename, location.first_line, "While loops are only allowed in constant functions!\n");
1819
1820 if (type == AST_REPEAT)
1821 {
1822 AstNode *count = children[0];
1823 AstNode *body = children[1];
1824
1825 // eval count expression
1826 while (count->simplify(true, false, false, stage, 32, true, false)) { }
1827
1828 if (count->type != AST_CONSTANT)
1829 log_file_error(filename, location.first_line, "Repeat loops outside must have constant repeat counts!\n");
1830
1831 // convert to a block with the body repeated n times
1832 type = AST_BLOCK;
1833 children.clear();
1834 for (int i = 0; i < count->bitsAsConst().as_int(); i++)
1835 children.insert(children.begin(), body->clone());
1836
1837 delete count;
1838 delete body;
1839 did_something = true;
1840 }
1841
1842 // unroll for loops and generate-for blocks
1843 if ((type == AST_GENFOR || type == AST_FOR) && children.size() != 0)
1844 {
1845 AstNode *init_ast = children[0];
1846 AstNode *while_ast = children[1];
1847 AstNode *next_ast = children[2];
1848 AstNode *body_ast = children[3];
1849
1850 while (body_ast->type == AST_GENBLOCK && body_ast->str.empty() &&
1851 body_ast->children.size() == 1 && body_ast->children.at(0)->type == AST_GENBLOCK)
1852 body_ast = body_ast->children.at(0);
1853
1854 const char* loop_type_str = "procedural";
1855 const char* var_type_str = "register";
1856 AstNodeType var_type = AST_WIRE;
1857 if (type == AST_GENFOR) {
1858 loop_type_str = "generate";
1859 var_type_str = "genvar";
1860 var_type = AST_GENVAR;
1861 }
1862
1863 if (init_ast->type != AST_ASSIGN_EQ)
1864 log_file_error(filename, location.first_line, "Unsupported 1st expression of %s for-loop!\n", loop_type_str);
1865 if (next_ast->type != AST_ASSIGN_EQ)
1866 log_file_error(filename, location.first_line, "Unsupported 3rd expression of %s for-loop!\n", loop_type_str);
1867
1868 if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != var_type)
1869 log_file_error(filename, location.first_line, "Left hand side of 1st expression of %s for-loop is not a %s!\n", loop_type_str, var_type_str);
1870 if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != var_type)
1871 log_file_error(filename, location.first_line, "Left hand side of 3rd expression of %s for-loop is not a %s!\n", loop_type_str, var_type_str);
1872
1873 if (init_ast->children[0]->id2ast != next_ast->children[0]->id2ast)
1874 log_file_error(filename, location.first_line, "Incompatible left-hand sides in 1st and 3rd expression of %s for-loop!\n", loop_type_str);
1875
1876 // eval 1st expression
1877 AstNode *varbuf = init_ast->children[1]->clone();
1878 {
1879 int expr_width_hint = -1;
1880 bool expr_sign_hint = true;
1881 varbuf->detectSignWidth(expr_width_hint, expr_sign_hint);
1882 while (varbuf->simplify(true, false, false, stage, 32, true, false)) { }
1883 }
1884
1885 if (varbuf->type != AST_CONSTANT)
1886 log_file_error(filename, location.first_line, "Right hand side of 1st expression of %s for-loop is not constant!\n", loop_type_str);
1887
1888 auto resolved = current_scope.at(init_ast->children[0]->str);
1889 if (resolved->range_valid) {
1890 int const_size = varbuf->range_left - varbuf->range_right;
1891 int resolved_size = resolved->range_left - resolved->range_right;
1892 if (const_size < resolved_size) {
1893 for (int i = const_size; i < resolved_size; i++)
1894 varbuf->bits.push_back(resolved->is_signed ? varbuf->bits.back() : State::S0);
1895 varbuf->range_left = resolved->range_left;
1896 varbuf->range_right = resolved->range_right;
1897 varbuf->range_swapped = resolved->range_swapped;
1898 varbuf->range_valid = resolved->range_valid;
1899 }
1900 }
1901
1902 varbuf = new AstNode(AST_LOCALPARAM, varbuf);
1903 varbuf->str = init_ast->children[0]->str;
1904
1905 AstNode *backup_scope_varbuf = current_scope[varbuf->str];
1906 current_scope[varbuf->str] = varbuf;
1907
1908 size_t current_block_idx = 0;
1909 if (type == AST_FOR) {
1910 while (current_block_idx < current_block->children.size() &&
1911 current_block->children[current_block_idx] != current_block_child)
1912 current_block_idx++;
1913 }
1914
1915 while (1)
1916 {
1917 // eval 2nd expression
1918 AstNode *buf = while_ast->clone();
1919 {
1920 int expr_width_hint = -1;
1921 bool expr_sign_hint = true;
1922 buf->detectSignWidth(expr_width_hint, expr_sign_hint);
1923 while (buf->simplify(true, false, false, stage, expr_width_hint, expr_sign_hint, false)) { }
1924 }
1925
1926 if (buf->type != AST_CONSTANT)
1927 log_file_error(filename, location.first_line, "2nd expression of %s for-loop is not constant!\n", loop_type_str);
1928
1929 if (buf->integer == 0) {
1930 delete buf;
1931 break;
1932 }
1933 delete buf;
1934
1935 // expand body
1936 int index = varbuf->children[0]->integer;
1937 log_assert(body_ast->type == AST_GENBLOCK || body_ast->type == AST_BLOCK);
1938 log_assert(!body_ast->str.empty());
1939 buf = body_ast->clone();
1940
1941 std::stringstream sstr;
1942 sstr << buf->str << "[" << index << "].";
1943 std::string prefix = sstr.str();
1944
1945 // create a scoped localparam for the current value of the loop variable
1946 AstNode *local_index = varbuf->clone();
1947 size_t pos = local_index->str.rfind('.');
1948 if (pos != std::string::npos) // remove outer prefix
1949 local_index->str = "\\" + local_index->str.substr(pos + 1);
1950 local_index->str = prefix_id(prefix, local_index->str);
1951 current_scope[local_index->str] = local_index;
1952 current_ast_mod->children.push_back(local_index);
1953
1954 buf->expand_genblock(prefix);
1955
1956 if (type == AST_GENFOR) {
1957 for (size_t i = 0; i < buf->children.size(); i++) {
1958 buf->children[i]->simplify(const_fold, false, false, stage, -1, false, false);
1959 current_ast_mod->children.push_back(buf->children[i]);
1960 }
1961 } else {
1962 for (size_t i = 0; i < buf->children.size(); i++)
1963 current_block->children.insert(current_block->children.begin() + current_block_idx++, buf->children[i]);
1964 }
1965 buf->children.clear();
1966 delete buf;
1967
1968 // eval 3rd expression
1969 buf = next_ast->children[1]->clone();
1970 {
1971 int expr_width_hint = -1;
1972 bool expr_sign_hint = true;
1973 buf->detectSignWidth(expr_width_hint, expr_sign_hint);
1974 while (buf->simplify(true, false, false, stage, expr_width_hint, expr_sign_hint, true)) { }
1975 }
1976
1977 if (buf->type != AST_CONSTANT)
1978 log_file_error(filename, location.first_line, "Right hand side of 3rd expression of %s for-loop is not constant (%s)!\n", loop_type_str, type2str(buf->type).c_str());
1979
1980 delete varbuf->children[0];
1981 varbuf->children[0] = buf;
1982 }
1983
1984 if (type == AST_FOR) {
1985 AstNode *buf = next_ast->clone();
1986 delete buf->children[1];
1987 buf->children[1] = varbuf->children[0]->clone();
1988 current_block->children.insert(current_block->children.begin() + current_block_idx++, buf);
1989 }
1990
1991 current_scope[varbuf->str] = backup_scope_varbuf;
1992 delete varbuf;
1993 delete_children();
1994 did_something = true;
1995 }
1996
1997 // check for local objects in unnamed block
1998 if (type == AST_BLOCK && str.empty())
1999 {
2000 for (size_t i = 0; i < children.size(); i++)
2001 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)
2002 {
2003 log_assert(!VERILOG_FRONTEND::sv_mode);
2004 log_file_error(children[i]->filename, children[i]->location.first_line, "Local declaration in unnamed block is only supported in SystemVerilog mode!\n");
2005 }
2006 }
2007
2008 // transform block with name
2009 if (type == AST_BLOCK && !str.empty())
2010 {
2011 expand_genblock(str + ".");
2012
2013 std::vector<AstNode*> new_children;
2014 for (size_t i = 0; i < children.size(); i++)
2015 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) {
2016 children[i]->simplify(false, false, false, stage, -1, false, false);
2017 current_ast_mod->children.push_back(children[i]);
2018 current_scope[children[i]->str] = children[i];
2019 } else
2020 new_children.push_back(children[i]);
2021
2022 children.swap(new_children);
2023 did_something = true;
2024 str.clear();
2025 }
2026
2027 // simplify unconditional generate block
2028 if (type == AST_GENBLOCK && children.size() != 0)
2029 {
2030 if (!str.empty()) {
2031 expand_genblock(str + ".");
2032 }
2033
2034 for (size_t i = 0; i < children.size(); i++) {
2035 children[i]->simplify(const_fold, false, false, stage, -1, false, false);
2036 current_ast_mod->children.push_back(children[i]);
2037 }
2038
2039 children.clear();
2040 did_something = true;
2041 }
2042
2043 // simplify generate-if blocks
2044 if (type == AST_GENIF && children.size() != 0)
2045 {
2046 AstNode *buf = children[0]->clone();
2047 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
2048 if (buf->type != AST_CONSTANT) {
2049 // for (auto f : log_files)
2050 // dumpAst(f, "verilog-ast> ");
2051 log_file_error(filename, location.first_line, "Condition for generate if is not constant!\n");
2052 }
2053 if (buf->asBool() != 0) {
2054 delete buf;
2055 buf = children[1]->clone();
2056 } else {
2057 delete buf;
2058 buf = children.size() > 2 ? children[2]->clone() : NULL;
2059 }
2060
2061 if (buf)
2062 {
2063 if (buf->type != AST_GENBLOCK)
2064 buf = new AstNode(AST_GENBLOCK, buf);
2065
2066 if (!buf->str.empty()) {
2067 buf->expand_genblock(buf->str + ".");
2068 }
2069
2070 for (size_t i = 0; i < buf->children.size(); i++) {
2071 buf->children[i]->simplify(const_fold, false, false, stage, -1, false, false);
2072 current_ast_mod->children.push_back(buf->children[i]);
2073 }
2074
2075 buf->children.clear();
2076 delete buf;
2077 }
2078
2079 delete_children();
2080 did_something = true;
2081 }
2082
2083 // simplify generate-case blocks
2084 if (type == AST_GENCASE && children.size() != 0)
2085 {
2086 AstNode *buf = children[0]->clone();
2087 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
2088 if (buf->type != AST_CONSTANT) {
2089 // for (auto f : log_files)
2090 // dumpAst(f, "verilog-ast> ");
2091 log_file_error(filename, location.first_line, "Condition for generate case is not constant!\n");
2092 }
2093
2094 bool ref_signed = buf->is_signed;
2095 RTLIL::Const ref_value = buf->bitsAsConst();
2096 delete buf;
2097
2098 AstNode *selected_case = NULL;
2099 for (size_t i = 1; i < children.size(); i++)
2100 {
2101 log_assert(children.at(i)->type == AST_COND || children.at(i)->type == AST_CONDX || children.at(i)->type == AST_CONDZ);
2102
2103 AstNode *this_genblock = NULL;
2104 for (auto child : children.at(i)->children) {
2105 log_assert(this_genblock == NULL);
2106 if (child->type == AST_GENBLOCK)
2107 this_genblock = child;
2108 }
2109
2110 for (auto child : children.at(i)->children)
2111 {
2112 if (child->type == AST_DEFAULT) {
2113 if (selected_case == NULL)
2114 selected_case = this_genblock;
2115 continue;
2116 }
2117 if (child->type == AST_GENBLOCK)
2118 continue;
2119
2120 buf = child->clone();
2121 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, true)) { }
2122 if (buf->type != AST_CONSTANT) {
2123 // for (auto f : log_files)
2124 // dumpAst(f, "verilog-ast> ");
2125 log_file_error(filename, location.first_line, "Expression in generate case is not constant!\n");
2126 }
2127
2128 bool is_selected = RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool();
2129 delete buf;
2130
2131 if (is_selected) {
2132 selected_case = this_genblock;
2133 i = children.size();
2134 break;
2135 }
2136 }
2137 }
2138
2139 if (selected_case != NULL)
2140 {
2141 log_assert(selected_case->type == AST_GENBLOCK);
2142 buf = selected_case->clone();
2143
2144 if (!buf->str.empty()) {
2145 buf->expand_genblock(buf->str + ".");
2146 }
2147
2148 for (size_t i = 0; i < buf->children.size(); i++) {
2149 buf->children[i]->simplify(const_fold, false, false, stage, -1, false, false);
2150 current_ast_mod->children.push_back(buf->children[i]);
2151 }
2152
2153 buf->children.clear();
2154 delete buf;
2155 }
2156
2157 delete_children();
2158 did_something = true;
2159 }
2160
2161 // unroll cell arrays
2162 if (type == AST_CELLARRAY)
2163 {
2164 if (!children.at(0)->range_valid)
2165 log_file_error(filename, location.first_line, "Non-constant array range on cell array.\n");
2166
2167 newNode = new AstNode(AST_GENBLOCK);
2168 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;
2169
2170 for (int i = 0; i < num; i++) {
2171 int idx = children.at(0)->range_left > children.at(0)->range_right ? children.at(0)->range_right + i : children.at(0)->range_right - i;
2172 AstNode *new_cell = children.at(1)->clone();
2173 newNode->children.push_back(new_cell);
2174 new_cell->str += stringf("[%d]", idx);
2175 if (new_cell->type == AST_PRIMITIVE) {
2176 log_file_error(filename, location.first_line, "Cell arrays of primitives are currently not supported.\n");
2177 } else {
2178 log_assert(new_cell->children.at(0)->type == AST_CELLTYPE);
2179 new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str.c_str());
2180 }
2181 }
2182
2183 goto apply_newNode;
2184 }
2185
2186 // replace primitives with assignments
2187 if (type == AST_PRIMITIVE)
2188 {
2189 if (children.size() < 2)
2190 log_file_error(filename, location.first_line, "Insufficient number of arguments for primitive `%s'!\n", str.c_str());
2191
2192 std::vector<AstNode*> children_list;
2193 for (auto child : children) {
2194 log_assert(child->type == AST_ARGUMENT);
2195 log_assert(child->children.size() == 1);
2196 children_list.push_back(child->children[0]);
2197 child->children.clear();
2198 delete child;
2199 }
2200 children.clear();
2201
2202 if (str == "bufif0" || str == "bufif1" || str == "notif0" || str == "notif1")
2203 {
2204 if (children_list.size() != 3)
2205 log_file_error(filename, location.first_line, "Invalid number of arguments for primitive `%s'!\n", str.c_str());
2206
2207 std::vector<RTLIL::State> z_const(1, RTLIL::State::Sz);
2208
2209 AstNode *mux_input = children_list.at(1);
2210 if (str == "notif0" || str == "notif1") {
2211 mux_input = new AstNode(AST_BIT_NOT, mux_input);
2212 }
2213 AstNode *node = new AstNode(AST_TERNARY, children_list.at(2));
2214 if (str == "bufif0") {
2215 node->children.push_back(AstNode::mkconst_bits(z_const, false));
2216 node->children.push_back(mux_input);
2217 } else {
2218 node->children.push_back(mux_input);
2219 node->children.push_back(AstNode::mkconst_bits(z_const, false));
2220 }
2221
2222 str.clear();
2223 type = AST_ASSIGN;
2224 children.push_back(children_list.at(0));
2225 children.back()->was_checked = true;
2226 children.push_back(node);
2227 did_something = true;
2228 }
2229 else if (str == "buf" || str == "not")
2230 {
2231 AstNode *input = children_list.back();
2232 if (str == "not")
2233 input = new AstNode(AST_BIT_NOT, input);
2234
2235 newNode = new AstNode(AST_GENBLOCK);
2236 for (auto it = children_list.begin(); it != std::prev(children_list.end()); it++) {
2237 newNode->children.push_back(new AstNode(AST_ASSIGN, *it, input->clone()));
2238 newNode->children.back()->was_checked = true;
2239 }
2240 delete input;
2241
2242 did_something = true;
2243 }
2244 else
2245 {
2246 AstNodeType op_type = AST_NONE;
2247 bool invert_results = false;
2248
2249 if (str == "and")
2250 op_type = AST_BIT_AND;
2251 if (str == "nand")
2252 op_type = AST_BIT_AND, invert_results = true;
2253 if (str == "or")
2254 op_type = AST_BIT_OR;
2255 if (str == "nor")
2256 op_type = AST_BIT_OR, invert_results = true;
2257 if (str == "xor")
2258 op_type = AST_BIT_XOR;
2259 if (str == "xnor")
2260 op_type = AST_BIT_XOR, invert_results = true;
2261 log_assert(op_type != AST_NONE);
2262
2263 AstNode *node = children_list[1];
2264 if (op_type != AST_POS)
2265 for (size_t i = 2; i < children_list.size(); i++) {
2266 node = new AstNode(op_type, node, children_list[i]);
2267 node->location = location;
2268 }
2269 if (invert_results)
2270 node = new AstNode(AST_BIT_NOT, node);
2271
2272 str.clear();
2273 type = AST_ASSIGN;
2274 children.push_back(children_list[0]);
2275 children.back()->was_checked = true;
2276 children.push_back(node);
2277 did_something = true;
2278 }
2279 }
2280
2281 // replace dynamic ranges in left-hand side expressions (e.g. "foo[bar] <= 1'b1;") with
2282 // either a big case block that selects the correct single-bit assignment, or mask and
2283 // shift operations.
2284 if (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE)
2285 {
2286 if (children[0]->type != AST_IDENTIFIER || children[0]->children.size() == 0)
2287 goto skip_dynamic_range_lvalue_expansion;
2288 if (children[0]->children[0]->range_valid || did_something)
2289 goto skip_dynamic_range_lvalue_expansion;
2290 if (children[0]->id2ast == NULL || children[0]->id2ast->type != AST_WIRE)
2291 goto skip_dynamic_range_lvalue_expansion;
2292 if (!children[0]->id2ast->range_valid)
2293 goto skip_dynamic_range_lvalue_expansion;
2294
2295 int source_width = children[0]->id2ast->range_left - children[0]->id2ast->range_right + 1;
2296 int result_width = 1;
2297
2298 AstNode *shift_expr = NULL;
2299 AstNode *range = children[0]->children[0];
2300
2301 if (range->children.size() == 1) {
2302 shift_expr = range->children[0]->clone();
2303 } else {
2304 shift_expr = range->children[1]->clone();
2305 AstNode *left_at_zero_ast = range->children[0]->clone();
2306 AstNode *right_at_zero_ast = range->children[1]->clone();
2307 while (left_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { }
2308 while (right_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { }
2309 if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
2310 log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
2311 result_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1;
2312 delete left_at_zero_ast;
2313 delete right_at_zero_ast;
2314 }
2315
2316 bool use_case_method = false;
2317
2318 if (children[0]->id2ast->attributes.count(ID::nowrshmsk)) {
2319 AstNode *node = children[0]->id2ast->attributes.at(ID::nowrshmsk);
2320 while (node->simplify(true, false, false, stage, -1, false, false)) { }
2321 if (node->type != AST_CONSTANT)
2322 log_file_error(filename, location.first_line, "Non-constant value for `nowrshmsk' attribute on `%s'!\n", children[0]->id2ast->str.c_str());
2323 if (node->asAttrConst().as_bool())
2324 use_case_method = true;
2325 }
2326
2327 if (!use_case_method && current_always->detect_latch(children[0]->str))
2328 use_case_method = true;
2329
2330 if (use_case_method)
2331 {
2332 // big case block
2333
2334 did_something = true;
2335 newNode = new AstNode(AST_CASE, shift_expr);
2336 for (int i = 0; i < source_width; i++) {
2337 int start_bit = children[0]->id2ast->range_right + i;
2338 int end_bit = std::min(start_bit+result_width,source_width) - 1;
2339 AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit, true));
2340 AstNode *lvalue = children[0]->clone();
2341 lvalue->delete_children();
2342 lvalue->children.push_back(new AstNode(AST_RANGE,
2343 mkconst_int(end_bit, true), mkconst_int(start_bit, true)));
2344 cond->children.push_back(new AstNode(AST_BLOCK, new AstNode(type, lvalue, children[1]->clone())));
2345 newNode->children.push_back(cond);
2346 }
2347 }
2348 else
2349 {
2350 // mask and shift operations, disabled for now
2351
2352 AstNode *wire_mask = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(source_width-1, true), mkconst_int(0, true)));
2353 wire_mask->str = stringf("$bitselwrite$mask$%s:%d$%d", filename.c_str(), location.first_line, autoidx++);
2354 wire_mask->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
2355 wire_mask->is_logic = true;
2356 while (wire_mask->simplify(true, false, false, 1, -1, false, false)) { }
2357 current_ast_mod->children.push_back(wire_mask);
2358
2359 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(source_width-1, true), mkconst_int(0, true)));
2360 wire_data->str = stringf("$bitselwrite$data$%s:%d$%d", filename.c_str(), location.first_line, autoidx++);
2361 wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
2362 wire_data->is_logic = true;
2363 while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
2364 current_ast_mod->children.push_back(wire_data);
2365
2366 did_something = true;
2367 newNode = new AstNode(AST_BLOCK);
2368
2369 AstNode *lvalue = children[0]->clone();
2370 lvalue->delete_children();
2371
2372 AstNode *ref_mask = new AstNode(AST_IDENTIFIER);
2373 ref_mask->str = wire_mask->str;
2374 ref_mask->id2ast = wire_mask;
2375 ref_mask->was_checked = true;
2376
2377 AstNode *ref_data = new AstNode(AST_IDENTIFIER);
2378 ref_data->str = wire_data->str;
2379 ref_data->id2ast = wire_data;
2380 ref_data->was_checked = true;
2381
2382 AstNode *old_data = lvalue->clone();
2383 if (type == AST_ASSIGN_LE)
2384 old_data->lookahead = true;
2385
2386 AstNode *shamt = shift_expr;
2387
2388 int shamt_width_hint = 0;
2389 bool shamt_sign_hint = true;
2390 shamt->detectSignWidth(shamt_width_hint, shamt_sign_hint);
2391
2392 int start_bit = children[0]->id2ast->range_right;
2393 bool use_shift = shamt_sign_hint;
2394
2395 if (start_bit != 0) {
2396 shamt = new AstNode(AST_SUB, shamt, mkconst_int(start_bit, true));
2397 use_shift = true;
2398 }
2399
2400 AstNode *t;
2401
2402 t = mkconst_bits(std::vector<RTLIL::State>(result_width, State::S1), false);
2403 if (use_shift)
2404 t = new AstNode(AST_SHIFT, t, new AstNode(AST_NEG, shamt->clone()));
2405 else
2406 t = new AstNode(AST_SHIFT_LEFT, t, shamt->clone());
2407 t = new AstNode(AST_ASSIGN_EQ, ref_mask->clone(), t);
2408 newNode->children.push_back(t);
2409
2410 t = new AstNode(AST_BIT_AND, mkconst_bits(std::vector<RTLIL::State>(result_width, State::S1), false), children[1]->clone());
2411 if (use_shift)
2412 t = new AstNode(AST_SHIFT, t, new AstNode(AST_NEG, shamt));
2413 else
2414 t = new AstNode(AST_SHIFT_LEFT, t, shamt);
2415 t = new AstNode(AST_ASSIGN_EQ, ref_data->clone(), t);
2416 newNode->children.push_back(t);
2417
2418 t = new AstNode(AST_BIT_AND, old_data, new AstNode(AST_BIT_NOT, ref_mask));
2419 t = new AstNode(AST_BIT_OR, t, ref_data);
2420 t = new AstNode(type, lvalue, t);
2421 newNode->children.push_back(t);
2422 }
2423
2424 goto apply_newNode;
2425 }
2426 skip_dynamic_range_lvalue_expansion:;
2427
2428 if (stage > 1 && (type == AST_ASSERT || type == AST_ASSUME || type == AST_LIVE || type == AST_FAIR || type == AST_COVER) && current_block != NULL)
2429 {
2430 std::stringstream sstr;
2431 sstr << "$formal$" << filename << ":" << location.first_line << "$" << (autoidx++);
2432 std::string id_check = sstr.str() + "_CHECK", id_en = sstr.str() + "_EN";
2433
2434 AstNode *wire_check = new AstNode(AST_WIRE);
2435 wire_check->str = id_check;
2436 wire_check->was_checked = true;
2437 current_ast_mod->children.push_back(wire_check);
2438 current_scope[wire_check->str] = wire_check;
2439 while (wire_check->simplify(true, false, false, 1, -1, false, false)) { }
2440
2441 AstNode *wire_en = new AstNode(AST_WIRE);
2442 wire_en->str = id_en;
2443 wire_en->was_checked = true;
2444 current_ast_mod->children.push_back(wire_en);
2445 if (current_always_clocked) {
2446 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)))));
2447 current_ast_mod->children.back()->children[0]->children[0]->children[0]->str = id_en;
2448 current_ast_mod->children.back()->children[0]->children[0]->children[0]->was_checked = true;
2449 }
2450 current_scope[wire_en->str] = wire_en;
2451 while (wire_en->simplify(true, false, false, 1, -1, false, false)) { }
2452
2453 AstNode *check_defval;
2454 if (type == AST_LIVE || type == AST_FAIR) {
2455 check_defval = new AstNode(AST_REDUCE_BOOL, children[0]->clone());
2456 } else {
2457 std::vector<RTLIL::State> x_bit;
2458 x_bit.push_back(RTLIL::State::Sx);
2459 check_defval = mkconst_bits(x_bit, false);
2460 }
2461
2462 AstNode *assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), check_defval);
2463 assign_check->children[0]->str = id_check;
2464 assign_check->children[0]->was_checked = true;
2465
2466 AstNode *assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, 1));
2467 assign_en->children[0]->str = id_en;
2468 assign_en->children[0]->was_checked = true;
2469
2470 AstNode *default_signals = new AstNode(AST_BLOCK);
2471 default_signals->children.push_back(assign_check);
2472 default_signals->children.push_back(assign_en);
2473 current_top_block->children.insert(current_top_block->children.begin(), default_signals);
2474
2475 if (type == AST_LIVE || type == AST_FAIR) {
2476 assign_check = nullptr;
2477 } else {
2478 assign_check = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_REDUCE_BOOL, children[0]->clone()));
2479 assign_check->children[0]->str = id_check;
2480 assign_check->children[0]->was_checked = true;
2481 }
2482
2483 if (current_always == nullptr || current_always->type != AST_INITIAL) {
2484 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), mkconst_int(1, false, 1));
2485 } else {
2486 assign_en = new AstNode(AST_ASSIGN_LE, new AstNode(AST_IDENTIFIER), new AstNode(AST_FCALL));
2487 assign_en->children[1]->str = "\\$initstate";
2488 }
2489 assign_en->children[0]->str = id_en;
2490 assign_en->children[0]->was_checked = true;
2491
2492 newNode = new AstNode(AST_BLOCK);
2493 if (assign_check != nullptr)
2494 newNode->children.push_back(assign_check);
2495 newNode->children.push_back(assign_en);
2496
2497 AstNode *assertnode = new AstNode(type);
2498 assertnode->location = location;
2499 assertnode->str = str;
2500 assertnode->children.push_back(new AstNode(AST_IDENTIFIER));
2501 assertnode->children.push_back(new AstNode(AST_IDENTIFIER));
2502 assertnode->children[0]->str = id_check;
2503 assertnode->children[1]->str = id_en;
2504 assertnode->attributes.swap(attributes);
2505 current_ast_mod->children.push_back(assertnode);
2506
2507 goto apply_newNode;
2508 }
2509
2510 if (stage > 1 && (type == AST_ASSERT || type == AST_ASSUME || type == AST_LIVE || type == AST_FAIR || type == AST_COVER) && children.size() == 1)
2511 {
2512 children.push_back(mkconst_int(1, false, 1));
2513 did_something = true;
2514 }
2515
2516 // found right-hand side identifier for memory -> replace with memory read port
2517 if (stage > 1 && type == AST_IDENTIFIER && id2ast != NULL && id2ast->type == AST_MEMORY && !in_lvalue &&
2518 children.size() == 1 && children[0]->type == AST_RANGE && children[0]->children.size() == 1) {
2519 newNode = new AstNode(AST_MEMRD, children[0]->children[0]->clone());
2520 newNode->str = str;
2521 newNode->id2ast = id2ast;
2522 goto apply_newNode;
2523 }
2524
2525 // assignment with nontrivial member in left-hand concat expression -> split assignment
2526 if ((type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) && children[0]->type == AST_CONCAT && width_hint > 0)
2527 {
2528 bool found_nontrivial_member = false;
2529
2530 for (auto child : children[0]->children) {
2531 if (child->type == AST_IDENTIFIER && child->id2ast != NULL && child->id2ast->type == AST_MEMORY)
2532 found_nontrivial_member = true;
2533 }
2534
2535 if (found_nontrivial_member)
2536 {
2537 newNode = new AstNode(AST_BLOCK);
2538
2539 AstNode *wire_tmp = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(width_hint-1, true), mkconst_int(0, true)));
2540 wire_tmp->str = stringf("$splitcmplxassign$%s:%d$%d", filename.c_str(), location.first_line, autoidx++);
2541 current_ast_mod->children.push_back(wire_tmp);
2542 current_scope[wire_tmp->str] = wire_tmp;
2543 wire_tmp->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
2544 while (wire_tmp->simplify(true, false, false, 1, -1, false, false)) { }
2545 wire_tmp->is_logic = true;
2546
2547 AstNode *wire_tmp_id = new AstNode(AST_IDENTIFIER);
2548 wire_tmp_id->str = wire_tmp->str;
2549
2550 newNode->children.push_back(new AstNode(AST_ASSIGN_EQ, wire_tmp_id, children[1]->clone()));
2551 newNode->children.back()->was_checked = true;
2552
2553 int cursor = 0;
2554 for (auto child : children[0]->children)
2555 {
2556 int child_width_hint = -1;
2557 bool child_sign_hint = true;
2558 child->detectSignWidth(child_width_hint, child_sign_hint);
2559
2560 AstNode *rhs = wire_tmp_id->clone();
2561 rhs->children.push_back(new AstNode(AST_RANGE, AstNode::mkconst_int(cursor+child_width_hint-1, true), AstNode::mkconst_int(cursor, true)));
2562 newNode->children.push_back(new AstNode(type, child->clone(), rhs));
2563
2564 cursor += child_width_hint;
2565 }
2566
2567 goto apply_newNode;
2568 }
2569 }
2570
2571 // assignment with memory in left-hand side expression -> replace with memory write port
2572 if (stage > 1 && (type == AST_ASSIGN_EQ || type == AST_ASSIGN_LE) && children[0]->type == AST_IDENTIFIER &&
2573 children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY && children[0]->id2ast->children.size() >= 2 &&
2574 children[0]->id2ast->children[0]->range_valid && children[0]->id2ast->children[1]->range_valid &&
2575 (children[0]->children.size() == 1 || children[0]->children.size() == 2) && children[0]->children[0]->type == AST_RANGE)
2576 {
2577 std::stringstream sstr;
2578 sstr << "$memwr$" << children[0]->str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
2579 std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA", id_en = sstr.str() + "_EN";
2580
2581 int mem_width, mem_size, addr_bits;
2582 bool mem_signed = children[0]->id2ast->is_signed;
2583 children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
2584
2585 newNode = new AstNode(AST_BLOCK);
2586 AstNode *defNode = new AstNode(AST_BLOCK);
2587
2588 int data_range_left = children[0]->id2ast->children[0]->range_left;
2589 int data_range_right = children[0]->id2ast->children[0]->range_right;
2590 int mem_data_range_offset = std::min(data_range_left, data_range_right);
2591
2592 int addr_width_hint = -1;
2593 bool addr_sign_hint = true;
2594 children[0]->children[0]->children[0]->detectSignWidthWorker(addr_width_hint, addr_sign_hint);
2595 addr_bits = std::max(addr_bits, addr_width_hint);
2596
2597 std::vector<RTLIL::State> x_bits_addr, x_bits_data, set_bits_en;
2598 for (int i = 0; i < addr_bits; i++)
2599 x_bits_addr.push_back(RTLIL::State::Sx);
2600 for (int i = 0; i < mem_width; i++)
2601 x_bits_data.push_back(RTLIL::State::Sx);
2602 for (int i = 0; i < mem_width; i++)
2603 set_bits_en.push_back(RTLIL::State::S1);
2604
2605 AstNode *node_addr = nullptr;
2606 if (children[0]->children[0]->children[0]->isConst()) {
2607 node_addr = children[0]->children[0]->children[0]->clone();
2608 } else {
2609 AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
2610 wire_addr->str = id_addr;
2611 wire_addr->was_checked = true;
2612 current_ast_mod->children.push_back(wire_addr);
2613 current_scope[wire_addr->str] = wire_addr;
2614 while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
2615
2616 AstNode *assign_addr = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false));
2617 assign_addr->children[0]->str = id_addr;
2618 assign_addr->children[0]->was_checked = true;
2619 defNode->children.push_back(assign_addr);
2620
2621 assign_addr = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());
2622 assign_addr->children[0]->str = id_addr;
2623 assign_addr->children[0]->was_checked = true;
2624 newNode->children.push_back(assign_addr);
2625
2626 node_addr = new AstNode(AST_IDENTIFIER);
2627 node_addr->str = id_addr;
2628 }
2629
2630 AstNode *node_data = nullptr;
2631 if (children[0]->children.size() == 1 && children[1]->isConst()) {
2632 node_data = children[1]->clone();
2633 } else {
2634 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
2635 wire_data->str = id_data;
2636 wire_data->was_checked = true;
2637 wire_data->is_signed = mem_signed;
2638 current_ast_mod->children.push_back(wire_data);
2639 current_scope[wire_data->str] = wire_data;
2640 while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
2641
2642 AstNode *assign_data = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false));
2643 assign_data->children[0]->str = id_data;
2644 assign_data->children[0]->was_checked = true;
2645 defNode->children.push_back(assign_data);
2646
2647 node_data = new AstNode(AST_IDENTIFIER);
2648 node_data->str = id_data;
2649 }
2650
2651 AstNode *wire_en = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
2652 wire_en->str = id_en;
2653 wire_en->was_checked = true;
2654 current_ast_mod->children.push_back(wire_en);
2655 current_scope[wire_en->str] = wire_en;
2656 while (wire_en->simplify(true, false, false, 1, -1, false, false)) { }
2657
2658 AstNode *assign_en_first = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width));
2659 assign_en_first->children[0]->str = id_en;
2660 assign_en_first->children[0]->was_checked = true;
2661 defNode->children.push_back(assign_en_first);
2662
2663 AstNode *node_en = new AstNode(AST_IDENTIFIER);
2664 node_en->str = id_en;
2665
2666 if (!defNode->children.empty())
2667 current_top_block->children.insert(current_top_block->children.begin(), defNode);
2668 else
2669 delete defNode;
2670
2671 AstNode *assign_data = nullptr;
2672 AstNode *assign_en = nullptr;
2673 if (children[0]->children.size() == 2)
2674 {
2675 if (children[0]->children[1]->range_valid)
2676 {
2677 int offset = children[0]->children[1]->range_right;
2678 int width = children[0]->children[1]->range_left - offset + 1;
2679 offset -= mem_data_range_offset;
2680
2681 std::vector<RTLIL::State> padding_x(offset, RTLIL::State::Sx);
2682
2683 assign_data = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER),
2684 new AstNode(AST_CONCAT, mkconst_bits(padding_x, false), children[1]->clone()));
2685 assign_data->children[0]->str = id_data;
2686 assign_data->children[0]->was_checked = true;
2687
2688 for (int i = 0; i < mem_width; i++)
2689 set_bits_en[i] = offset <= i && i < offset+width ? RTLIL::State::S1 : RTLIL::State::S0;
2690 assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));
2691 assign_en->children[0]->str = id_en;
2692 assign_en->children[0]->was_checked = true;
2693 }
2694 else
2695 {
2696 AstNode *the_range = children[0]->children[1];
2697 AstNode *left_at_zero_ast = the_range->children[0]->clone();
2698 AstNode *right_at_zero_ast = the_range->children.size() >= 2 ? the_range->children[1]->clone() : left_at_zero_ast->clone();
2699 AstNode *offset_ast = right_at_zero_ast->clone();
2700
2701 if (mem_data_range_offset)
2702 offset_ast = new AstNode(AST_SUB, offset_ast, mkconst_int(mem_data_range_offset, true));
2703
2704 while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }
2705 while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { }
2706 if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT)
2707 log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str());
2708 int width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1;
2709
2710 assign_data = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER),
2711 new AstNode(AST_SHIFT_LEFT, children[1]->clone(), offset_ast->clone()));
2712 assign_data->children[0]->str = id_data;
2713 assign_data->children[0]->was_checked = true;
2714
2715 for (int i = 0; i < mem_width; i++)
2716 set_bits_en[i] = i < width ? RTLIL::State::S1 : RTLIL::State::S0;
2717 assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER),
2718 new AstNode(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone()));
2719 assign_en->children[0]->str = id_en;
2720 assign_en->children[0]->was_checked = true;
2721
2722 delete left_at_zero_ast;
2723 delete right_at_zero_ast;
2724 delete offset_ast;
2725 }
2726 }
2727 else
2728 {
2729 if (!(children[0]->children.size() == 1 && children[1]->isConst())) {
2730 assign_data = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), children[1]->clone());
2731 assign_data->children[0]->str = id_data;
2732 assign_data->children[0]->was_checked = true;
2733 }
2734
2735 assign_en = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(set_bits_en, false));
2736 assign_en->children[0]->str = id_en;
2737 assign_en->children[0]->was_checked = true;
2738 }
2739 if (assign_data)
2740 newNode->children.push_back(assign_data);
2741 if (assign_en)
2742 newNode->children.push_back(assign_en);
2743
2744 AstNode *wrnode;
2745 if (current_always->type == AST_INITIAL)
2746 wrnode = new AstNode(AST_MEMINIT, node_addr, node_data, node_en, mkconst_int(1, false));
2747 else
2748 wrnode = new AstNode(AST_MEMWR, node_addr, node_data, node_en);
2749 wrnode->str = children[0]->str;
2750 wrnode->id2ast = children[0]->id2ast;
2751 wrnode->location = location;
2752 if (wrnode->type == AST_MEMWR) {
2753 int portid = current_memwr_count[wrnode->str]++;
2754 wrnode->children.push_back(mkconst_int(portid, false));
2755 std::vector<RTLIL::State> priority_mask;
2756 for (int i = 0; i < portid; i++) {
2757 bool has_prio = current_memwr_visible[wrnode->str].count(i);
2758 priority_mask.push_back(State(has_prio));
2759 }
2760 wrnode->children.push_back(mkconst_bits(priority_mask, false));
2761 current_memwr_visible[wrnode->str].insert(portid);
2762 current_always->children.push_back(wrnode);
2763 } else {
2764 current_ast_mod->children.push_back(wrnode);
2765 }
2766
2767 if (newNode->children.empty()) {
2768 delete newNode;
2769 newNode = new AstNode();
2770 }
2771 goto apply_newNode;
2772 }
2773
2774 // replace function and task calls with the code from the function or task
2775 if ((type == AST_FCALL || type == AST_TCALL) && !str.empty())
2776 {
2777 if (type == AST_FCALL)
2778 {
2779 if (str == "\\$initstate")
2780 {
2781 int myidx = autoidx++;
2782
2783 AstNode *wire = new AstNode(AST_WIRE);
2784 wire->str = stringf("$initstate$%d_wire", myidx);
2785 current_ast_mod->children.push_back(wire);
2786 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
2787
2788 AstNode *cell = new AstNode(AST_CELL, new AstNode(AST_CELLTYPE), new AstNode(AST_ARGUMENT, new AstNode(AST_IDENTIFIER)));
2789 cell->str = stringf("$initstate$%d", myidx);
2790 cell->children[0]->str = "$initstate";
2791 cell->children[1]->str = "\\Y";
2792 cell->children[1]->children[0]->str = wire->str;
2793 cell->children[1]->children[0]->id2ast = wire;
2794 current_ast_mod->children.push_back(cell);
2795 while (cell->simplify(true, false, false, 1, -1, false, false)) { }
2796
2797 newNode = new AstNode(AST_IDENTIFIER);
2798 newNode->str = wire->str;
2799 newNode->id2ast = wire;
2800 goto apply_newNode;
2801 }
2802
2803 if (str == "\\$past")
2804 {
2805 if (width_hint < 0)
2806 goto replace_fcall_later;
2807
2808 int num_steps = 1;
2809
2810 if (GetSize(children) != 1 && GetSize(children) != 2)
2811 log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n",
2812 RTLIL::unescape_id(str).c_str(), int(children.size()));
2813
2814 if (!current_always_clocked)
2815 log_file_error(filename, location.first_line, "System function %s is only allowed in clocked blocks.\n",
2816 RTLIL::unescape_id(str).c_str());
2817
2818 if (GetSize(children) == 2)
2819 {
2820 AstNode *buf = children[1]->clone();
2821 while (buf->simplify(true, false, false, stage, -1, false, false)) { }
2822 if (buf->type != AST_CONSTANT)
2823 log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str());
2824
2825 num_steps = buf->asInt(true);
2826 delete buf;
2827 }
2828
2829 AstNode *block = nullptr;
2830
2831 for (auto child : current_always->children)
2832 if (child->type == AST_BLOCK)
2833 block = child;
2834
2835 log_assert(block != nullptr);
2836
2837 if (num_steps == 0) {
2838 newNode = children[0]->clone();
2839 goto apply_newNode;
2840 }
2841
2842 int myidx = autoidx++;
2843 AstNode *outreg = nullptr;
2844
2845 for (int i = 0; i < num_steps; i++)
2846 {
2847 AstNode *reg = new AstNode(AST_WIRE, new AstNode(AST_RANGE,
2848 mkconst_int(width_hint-1, true), mkconst_int(0, true)));
2849
2850 reg->str = stringf("$past$%s:%d$%d$%d", filename.c_str(), location.first_line, myidx, i);
2851 reg->is_reg = true;
2852
2853 current_ast_mod->children.push_back(reg);
2854
2855 while (reg->simplify(true, false, false, 1, -1, false, false)) { }
2856
2857 AstNode *regid = new AstNode(AST_IDENTIFIER);
2858 regid->str = reg->str;
2859 regid->id2ast = reg;
2860 regid->was_checked = true;
2861
2862 AstNode *rhs = nullptr;
2863
2864 if (outreg == nullptr) {
2865 rhs = children.at(0)->clone();
2866 } else {
2867 rhs = new AstNode(AST_IDENTIFIER);
2868 rhs->str = outreg->str;
2869 rhs->id2ast = outreg;
2870 }
2871
2872 block->children.push_back(new AstNode(AST_ASSIGN_LE, regid, rhs));
2873 outreg = reg;
2874 }
2875
2876 newNode = new AstNode(AST_IDENTIFIER);
2877 newNode->str = outreg->str;
2878 newNode->id2ast = outreg;
2879 goto apply_newNode;
2880 }
2881
2882 if (str == "\\$stable" || str == "\\$rose" || str == "\\$fell" || str == "\\$changed")
2883 {
2884 if (GetSize(children) != 1)
2885 log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
2886 RTLIL::unescape_id(str).c_str(), int(children.size()));
2887
2888 if (!current_always_clocked)
2889 log_file_error(filename, location.first_line, "System function %s is only allowed in clocked blocks.\n",
2890 RTLIL::unescape_id(str).c_str());
2891
2892 AstNode *present = children.at(0)->clone();
2893 AstNode *past = clone();
2894 past->str = "\\$past";
2895
2896 if (str == "\\$stable")
2897 newNode = new AstNode(AST_EQ, past, present);
2898
2899 else if (str == "\\$changed")
2900 newNode = new AstNode(AST_NE, past, present);
2901
2902 else if (str == "\\$rose")
2903 newNode = new AstNode(AST_LOGIC_AND,
2904 new AstNode(AST_LOGIC_NOT, new AstNode(AST_BIT_AND, past, mkconst_int(1,false))),
2905 new AstNode(AST_BIT_AND, present, mkconst_int(1,false)));
2906
2907 else if (str == "\\$fell")
2908 newNode = new AstNode(AST_LOGIC_AND,
2909 new AstNode(AST_BIT_AND, past, mkconst_int(1,false)),
2910 new AstNode(AST_LOGIC_NOT, new AstNode(AST_BIT_AND, present, mkconst_int(1,false))));
2911
2912 else
2913 log_abort();
2914
2915 goto apply_newNode;
2916 }
2917
2918 // $anyconst and $anyseq are mapped in AstNode::genRTLIL()
2919 if (str == "\\$anyconst" || str == "\\$anyseq" || str == "\\$allconst" || str == "\\$allseq") {
2920 recursion_counter--;
2921 return false;
2922 }
2923
2924 if (str == "\\$clog2")
2925 {
2926 if (children.size() != 1)
2927 log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
2928 RTLIL::unescape_id(str).c_str(), int(children.size()));
2929
2930 AstNode *buf = children[0]->clone();
2931 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
2932 if (buf->type != AST_CONSTANT)
2933 log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str());
2934
2935 RTLIL::Const arg_value = buf->bitsAsConst();
2936 if (arg_value.as_bool())
2937 arg_value = const_sub(arg_value, 1, false, false, GetSize(arg_value));
2938 delete buf;
2939
2940 uint32_t result = 0;
2941 for (size_t i = 0; i < arg_value.bits.size(); i++)
2942 if (arg_value.bits.at(i) == RTLIL::State::S1)
2943 result = i + 1;
2944
2945 newNode = mkconst_int(result, true);
2946 goto apply_newNode;
2947 }
2948
2949 if (str == "\\$size" || str == "\\$bits" || str == "\\$high" || str == "\\$low" || str == "\\$left" || str == "\\$right")
2950 {
2951 int dim = 1;
2952 if (str == "\\$bits") {
2953 if (children.size() != 1)
2954 log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
2955 RTLIL::unescape_id(str).c_str(), int(children.size()));
2956 } else {
2957 if (children.size() != 1 && children.size() != 2)
2958 log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n",
2959 RTLIL::unescape_id(str).c_str(), int(children.size()));
2960 if (children.size() == 2) {
2961 AstNode *buf = children[1]->clone();
2962 // Evaluate constant expression
2963 while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
2964 dim = buf->asInt(false);
2965 delete buf;
2966 }
2967 }
2968 AstNode *buf = children[0]->clone();
2969 int mem_depth = 1;
2970 int result, high = 0, low = 0, left = 0, right = 0, width = 1; // defaults for a simple wire
2971 AstNode *id_ast = NULL;
2972
2973 // Is this needed?
2974 //while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
2975 buf->detectSignWidth(width_hint, sign_hint);
2976
2977 if (buf->type == AST_IDENTIFIER) {
2978 id_ast = buf->id2ast;
2979 if (id_ast == NULL && current_scope.count(buf->str))
2980 id_ast = current_scope.at(buf->str);
2981 if (!id_ast)
2982 log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", buf->str.c_str());
2983 // a slice of our identifier means we advance to the next dimension, e.g. $size(a[3])
2984 if (buf->children.size() > 0) {
2985 // something is hanging below this identifier
2986 if (buf->children[0]->type == AST_RANGE && buf->integer == 0)
2987 // if integer == 0, this node was originally created as AST_RANGE so it's dimension is 1
2988 dim++;
2989 // more than one range, e.g. $size(a[3][2])
2990 else // created an AST_MULTIRANGE, converted to AST_RANGE, but original dimension saved in 'integer' field
2991 dim += buf->integer; // increment by multirange size
2992 }
2993 // We have 4 cases:
2994 // wire x; ==> AST_WIRE, no AST_RANGE children
2995 // wire [1:0]x; ==> AST_WIRE, AST_RANGE children
2996 // wire [1:0]x[1:0]; ==> AST_MEMORY, two AST_RANGE children (1st for packed, 2nd for unpacked)
2997 // wire [1:0]x[1:0][1:0]; ==> AST_MEMORY, one AST_RANGE child (0) for packed, then AST_MULTIRANGE child (1) for unpacked
2998 // (updated: actually by the time we are here, AST_MULTIRANGE is converted into one big AST_RANGE)
2999 // case 0 handled by default
3000 if ((id_ast->type == AST_WIRE || id_ast->type == AST_MEMORY) && id_ast->children.size() > 0) {
3001 // handle packed array left/right for case 1, and cases 2/3 when requesting the last dimension (packed side)
3002 AstNode *wire_range = id_ast->children[0];
3003 left = wire_range->children[0]->integer;
3004 right = wire_range->children[1]->integer;
3005 high = max(left, right);
3006 low = min(left, right);
3007 }
3008 if (id_ast->type == AST_MEMORY) {
3009 // We got here only if the argument is a memory
3010 // Otherwise $size() and $bits() return the expression width
3011 AstNode *mem_range = id_ast->children[1];
3012 if (str == "\\$bits") {
3013 if (mem_range->type == AST_RANGE) {
3014 if (!mem_range->range_valid)
3015 log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str());
3016 mem_depth = mem_range->range_left - mem_range->range_right + 1;
3017 } else
3018 log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str());
3019 } else {
3020 // $size(), $left(), $right(), $high(), $low()
3021 int dims = 1;
3022 if (mem_range->type == AST_RANGE) {
3023 if (id_ast->multirange_dimensions.empty()) {
3024 if (!mem_range->range_valid)
3025 log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str());
3026 if (dim == 1) {
3027 left = mem_range->range_right;
3028 right = mem_range->range_left;
3029 high = max(left, right);
3030 low = min(left, right);
3031 }
3032 } else {
3033 dims = GetSize(id_ast->multirange_dimensions)/2;
3034 if (dim <= dims) {
3035 width_hint = id_ast->multirange_dimensions[2*dim-1];
3036 high = id_ast->multirange_dimensions[2*dim-2] + id_ast->multirange_dimensions[2*dim-1] - 1;
3037 low = id_ast->multirange_dimensions[2*dim-2];
3038 if (id_ast->multirange_swapped[dim-1]) {
3039 left = low;
3040 right = high;
3041 } else {
3042 right = low;
3043 left = high;
3044 }
3045 } else if ((dim > dims+1) || (dim < 0))
3046 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);
3047 }
3048 } else {
3049 log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str());
3050 }
3051 }
3052 }
3053 width = high - low + 1;
3054 } else {
3055 width = width_hint;
3056 }
3057 delete buf;
3058 if (str == "\\$high")
3059 result = high;
3060 else if (str == "\\$low")
3061 result = low;
3062 else if (str == "\\$left")
3063 result = left;
3064 else if (str == "\\$right")
3065 result = right;
3066 else if (str == "\\$size")
3067 result = width;
3068 else {
3069 result = width * mem_depth;
3070 }
3071 newNode = mkconst_int(result, false);
3072 goto apply_newNode;
3073 }
3074
3075 if (str == "\\$ln" || str == "\\$log10" || str == "\\$exp" || str == "\\$sqrt" || str == "\\$pow" ||
3076 str == "\\$floor" || str == "\\$ceil" || str == "\\$sin" || str == "\\$cos" || str == "\\$tan" ||
3077 str == "\\$asin" || str == "\\$acos" || str == "\\$atan" || str == "\\$atan2" || str == "\\$hypot" ||
3078 str == "\\$sinh" || str == "\\$cosh" || str == "\\$tanh" || str == "\\$asinh" || str == "\\$acosh" || str == "\\$atanh" ||
3079 str == "\\$rtoi" || str == "\\$itor")
3080 {
3081 bool func_with_two_arguments = str == "\\$pow" || str == "\\$atan2" || str == "\\$hypot";
3082 double x = 0, y = 0;
3083
3084 if (func_with_two_arguments) {
3085 if (children.size() != 2)
3086 log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 2.\n",
3087 RTLIL::unescape_id(str).c_str(), int(children.size()));
3088 } else {
3089 if (children.size() != 1)
3090 log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
3091 RTLIL::unescape_id(str).c_str(), int(children.size()));
3092 }
3093
3094 if (children.size() >= 1) {
3095 while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
3096 if (!children[0]->isConst())
3097 log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant argument.\n",
3098 RTLIL::unescape_id(str).c_str());
3099 int child_width_hint = width_hint;
3100 bool child_sign_hint = sign_hint;
3101 children[0]->detectSignWidth(child_width_hint, child_sign_hint);
3102 x = children[0]->asReal(child_sign_hint);
3103 }
3104
3105 if (children.size() >= 2) {
3106 while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
3107 if (!children[1]->isConst())
3108 log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant argument.\n",
3109 RTLIL::unescape_id(str).c_str());
3110 int child_width_hint = width_hint;
3111 bool child_sign_hint = sign_hint;
3112 children[1]->detectSignWidth(child_width_hint, child_sign_hint);
3113 y = children[1]->asReal(child_sign_hint);
3114 }
3115
3116 if (str == "\\$rtoi") {
3117 newNode = AstNode::mkconst_int(x, true);
3118 } else {
3119 newNode = new AstNode(AST_REALVALUE);
3120 if (str == "\\$ln") newNode->realvalue = ::log(x);
3121 else if (str == "\\$log10") newNode->realvalue = ::log10(x);
3122 else if (str == "\\$exp") newNode->realvalue = ::exp(x);
3123 else if (str == "\\$sqrt") newNode->realvalue = ::sqrt(x);
3124 else if (str == "\\$pow") newNode->realvalue = ::pow(x, y);
3125 else if (str == "\\$floor") newNode->realvalue = ::floor(x);
3126 else if (str == "\\$ceil") newNode->realvalue = ::ceil(x);
3127 else if (str == "\\$sin") newNode->realvalue = ::sin(x);
3128 else if (str == "\\$cos") newNode->realvalue = ::cos(x);
3129 else if (str == "\\$tan") newNode->realvalue = ::tan(x);
3130 else if (str == "\\$asin") newNode->realvalue = ::asin(x);
3131 else if (str == "\\$acos") newNode->realvalue = ::acos(x);
3132 else if (str == "\\$atan") newNode->realvalue = ::atan(x);
3133 else if (str == "\\$atan2") newNode->realvalue = ::atan2(x, y);
3134 else if (str == "\\$hypot") newNode->realvalue = ::hypot(x, y);
3135 else if (str == "\\$sinh") newNode->realvalue = ::sinh(x);
3136 else if (str == "\\$cosh") newNode->realvalue = ::cosh(x);
3137 else if (str == "\\$tanh") newNode->realvalue = ::tanh(x);
3138 else if (str == "\\$asinh") newNode->realvalue = ::asinh(x);
3139 else if (str == "\\$acosh") newNode->realvalue = ::acosh(x);
3140 else if (str == "\\$atanh") newNode->realvalue = ::atanh(x);
3141 else if (str == "\\$itor") newNode->realvalue = x;
3142 else log_abort();
3143 }
3144 goto apply_newNode;
3145 }
3146
3147 if (str == "\\$sformatf") {
3148 AstNode *node_string = children[0];
3149 while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
3150 if (node_string->type != AST_CONSTANT)
3151 log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str());
3152 std::string sformat = node_string->bitsAsConst().decode_string();
3153 std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint);
3154 newNode = AstNode::mkconst_str(sout);
3155 goto apply_newNode;
3156 }
3157
3158 if (str == "\\$countbits") {
3159 if (children.size() < 2)
3160 log_file_error(filename, location.first_line, "System function %s got %d arguments, expected at least 2.\n",
3161 RTLIL::unescape_id(str).c_str(), int(children.size()));
3162
3163 std::vector<RTLIL::State> control_bits;
3164
3165 // Determine which bits to count
3166 for (size_t i = 1; i < children.size(); i++) {
3167 AstNode *node = children[i];
3168 while (node->simplify(true, false, false, stage, -1, false, false)) { }
3169 if (node->type != AST_CONSTANT)
3170 log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant control bit argument.\n", str.c_str());
3171 if (node->bits.size() != 1)
3172 log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with control bit width != 1.\n", str.c_str());
3173 control_bits.push_back(node->bits[0]);
3174 }
3175
3176 // Detect width of exp (first argument of $countbits)
3177 int exp_width = -1;
3178 bool exp_sign = false;
3179 AstNode *exp = children[0];
3180 exp->detectSignWidth(exp_width, exp_sign, NULL);
3181
3182 newNode = mkconst_int(0, false);
3183
3184 for (int i = 0; i < exp_width; i++) {
3185 // Generate nodes for: exp << i >> ($size(exp) - 1)
3186 // ^^ ^^
3187 AstNode *lsh_node = new AstNode(AST_SHIFT_LEFT, exp->clone(), mkconst_int(i, false));
3188 AstNode *rsh_node = new AstNode(AST_SHIFT_RIGHT, lsh_node, mkconst_int(exp_width - 1, false));
3189
3190 AstNode *or_node = nullptr;
3191
3192 for (RTLIL::State control_bit : control_bits) {
3193 // Generate node for: (exp << i >> ($size(exp) - 1)) === control_bit
3194 // ^^^
3195 AstNode *eq_node = new AstNode(AST_EQX, rsh_node->clone(), mkconst_bits({control_bit}, false));
3196
3197 // Or the result for each checked bit value
3198 if (or_node)
3199 or_node = new AstNode(AST_LOGIC_OR, or_node, eq_node);
3200 else
3201 or_node = eq_node;
3202 }
3203
3204 // We should have at least one element in control_bits,
3205 // because we checked for the number of arguments above
3206 log_assert(or_node != nullptr);
3207
3208 delete rsh_node;
3209
3210 // Generate node for adding with result of previous bit
3211 newNode = new AstNode(AST_ADD, newNode, or_node);
3212 }
3213
3214 goto apply_newNode;
3215 }
3216
3217 if (str == "\\$countones" || str == "\\$isunknown" || str == "\\$onehot" || str == "\\$onehot0") {
3218 if (children.size() != 1)
3219 log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n",
3220 RTLIL::unescape_id(str).c_str(), int(children.size()));
3221
3222 AstNode *countbits = clone();
3223 countbits->str = "\\$countbits";
3224
3225 if (str == "\\$countones") {
3226 countbits->children.push_back(mkconst_bits({RTLIL::State::S1}, false));
3227 newNode = countbits;
3228 } else if (str == "\\$isunknown") {
3229 countbits->children.push_back(mkconst_bits({RTLIL::Sx}, false));
3230 countbits->children.push_back(mkconst_bits({RTLIL::Sz}, false));
3231 newNode = new AstNode(AST_GT, countbits, mkconst_int(0, false));
3232 } else if (str == "\\$onehot") {
3233 countbits->children.push_back(mkconst_bits({RTLIL::State::S1}, false));
3234 newNode = new AstNode(AST_EQ, countbits, mkconst_int(1, false));
3235 } else if (str == "\\$onehot0") {
3236 countbits->children.push_back(mkconst_bits({RTLIL::State::S1}, false));
3237 newNode = new AstNode(AST_LE, countbits, mkconst_int(1, false));
3238 } else {
3239 log_abort();
3240 }
3241
3242 goto apply_newNode;
3243 }
3244
3245 if (current_scope.count(str) != 0 && current_scope[str]->type == AST_DPI_FUNCTION)
3246 {
3247 AstNode *dpi_decl = current_scope[str];
3248
3249 std::string rtype, fname;
3250 std::vector<std::string> argtypes;
3251 std::vector<AstNode*> args;
3252
3253 rtype = RTLIL::unescape_id(dpi_decl->children.at(0)->str);
3254 fname = RTLIL::unescape_id(dpi_decl->children.at(1)->str);
3255
3256 for (int i = 2; i < GetSize(dpi_decl->children); i++)
3257 {
3258 if (i-2 >= GetSize(children))
3259 log_file_error(filename, location.first_line, "Insufficient number of arguments in DPI function call.\n");
3260
3261 argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str));
3262 args.push_back(children.at(i-2)->clone());
3263 while (args.back()->simplify(true, false, false, stage, -1, false, true)) { }
3264
3265 if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE)
3266 log_file_error(filename, location.first_line, "Failed to evaluate DPI function with non-constant argument.\n");
3267 }
3268
3269 newNode = dpi_call(rtype, fname, argtypes, args);
3270
3271 for (auto arg : args)
3272 delete arg;
3273
3274 goto apply_newNode;
3275 }
3276
3277 if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION)
3278 log_file_error(filename, location.first_line, "Can't resolve function name `%s'.\n", str.c_str());
3279 }
3280
3281 if (type == AST_TCALL)
3282 {
3283 if (str == "$finish" || str == "$stop")
3284 {
3285 if (!current_always || current_always->type != AST_INITIAL)
3286 log_file_error(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str());
3287
3288 log_file_error(filename, location.first_line, "System task `%s' executed.\n", str.c_str());
3289 }
3290
3291 if (str == "\\$readmemh" || str == "\\$readmemb")
3292 {
3293 if (GetSize(children) < 2 || GetSize(children) > 4)
3294 log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 2-4.\n",
3295 RTLIL::unescape_id(str).c_str(), int(children.size()));
3296
3297 AstNode *node_filename = children[0]->clone();
3298 while (node_filename->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
3299 if (node_filename->type != AST_CONSTANT)
3300 log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str());
3301
3302 AstNode *node_memory = children[1]->clone();
3303 while (node_memory->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
3304 if (node_memory->type != AST_IDENTIFIER || node_memory->id2ast == nullptr || node_memory->id2ast->type != AST_MEMORY)
3305 log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str());
3306
3307 int start_addr = -1, finish_addr = -1;
3308
3309 if (GetSize(children) > 2) {
3310 AstNode *node_addr = children[2]->clone();
3311 while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
3312 if (node_addr->type != AST_CONSTANT)
3313 log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str());
3314 start_addr = int(node_addr->asInt(false));
3315 }
3316
3317 if (GetSize(children) > 3) {
3318 AstNode *node_addr = children[3]->clone();
3319 while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { }
3320 if (node_addr->type != AST_CONSTANT)
3321 log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str());
3322 finish_addr = int(node_addr->asInt(false));
3323 }
3324
3325 bool unconditional_init = false;
3326 if (current_always->type == AST_INITIAL) {
3327 pool<AstNode*> queue;
3328 log_assert(current_always->children[0]->type == AST_BLOCK);
3329 queue.insert(current_always->children[0]);
3330 while (!unconditional_init && !queue.empty()) {
3331 pool<AstNode*> next_queue;
3332 for (auto n : queue)
3333 for (auto c : n->children) {
3334 if (c == this)
3335 unconditional_init = true;
3336 next_queue.insert(c);
3337 }
3338 next_queue.swap(queue);
3339 }
3340 }
3341
3342 newNode = readmem(str == "\\$readmemh", node_filename->bitsAsConst().decode_string(), node_memory->id2ast, start_addr, finish_addr, unconditional_init);
3343 delete node_filename;
3344 delete node_memory;
3345 goto apply_newNode;
3346 }
3347
3348 if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK)
3349 log_file_error(filename, location.first_line, "Can't resolve task name `%s'.\n", str.c_str());
3350 }
3351
3352
3353 std::stringstream sstr;
3354 sstr << str << "$func$" << filename << ":" << location.first_line << "$" << (autoidx++) << '.';
3355 std::string prefix = sstr.str();
3356
3357 AstNode *decl = current_scope[str];
3358 if (unevaluated_tern_branch && decl->is_recursive_function())
3359 goto replace_fcall_later;
3360 decl = decl->clone();
3361 decl->replace_result_wire_name_in_function(str, "$result"); // enables recursion
3362 decl->expand_genblock(prefix);
3363
3364 if (decl->type == AST_FUNCTION && !decl->attributes.count(ID::via_celltype))
3365 {
3366 bool require_const_eval = decl->has_const_only_constructs();
3367 bool all_args_const = true;
3368 for (auto child : children) {
3369 while (child->simplify(true, false, false, 1, -1, false, true)) { }
3370 if (child->type != AST_CONSTANT && child->type != AST_REALVALUE)
3371 all_args_const = false;
3372 }
3373
3374 if (all_args_const) {
3375 AstNode *func_workspace = decl->clone();
3376 func_workspace->str = prefix_id(prefix, "$result");
3377 newNode = func_workspace->eval_const_function(this, in_param || require_const_eval);
3378 delete func_workspace;
3379 if (newNode) {
3380 delete decl;
3381 goto apply_newNode;
3382 }
3383 }
3384
3385 if (in_param)
3386 log_file_error(filename, location.first_line, "Non-constant function call in constant expression.\n");
3387 if (require_const_eval)
3388 log_file_error(filename, location.first_line, "Function %s can only be called with constant arguments.\n", str.c_str());
3389 }
3390
3391 size_t arg_count = 0;
3392 dict<std::string, AstNode*> wire_cache;
3393 vector<AstNode*> new_stmts;
3394 vector<AstNode*> output_assignments;
3395
3396 if (current_block == NULL)
3397 {
3398 log_assert(type == AST_FCALL);
3399
3400 AstNode *wire = NULL;
3401 std::string res_name = prefix_id(prefix, "$result");
3402 for (auto child : decl->children)
3403 if (child->type == AST_WIRE && child->str == res_name)
3404 wire = child->clone();
3405 log_assert(wire != NULL);
3406
3407 wire->port_id = 0;
3408 wire->is_input = false;
3409 wire->is_output = false;
3410
3411 current_scope[wire->str] = wire;
3412 current_ast_mod->children.push_back(wire);
3413 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
3414
3415 AstNode *lvalue = new AstNode(AST_IDENTIFIER);
3416 lvalue->str = wire->str;
3417
3418 AstNode *always = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK,
3419 new AstNode(AST_ASSIGN_EQ, lvalue, clone())));
3420 always->children[0]->children[0]->was_checked = true;
3421
3422 current_ast_mod->children.push_back(always);
3423
3424 goto replace_fcall_with_id;
3425 }
3426
3427 if (decl->attributes.count(ID::via_celltype))
3428 {
3429 std::string celltype = decl->attributes.at(ID::via_celltype)->asAttrConst().decode_string();
3430 std::string outport = str;
3431
3432 if (celltype.find(' ') != std::string::npos) {
3433 int pos = celltype.find(' ');
3434 outport = RTLIL::escape_id(celltype.substr(pos+1));
3435 celltype = RTLIL::escape_id(celltype.substr(0, pos));
3436 } else
3437 celltype = RTLIL::escape_id(celltype);
3438
3439 AstNode *cell = new AstNode(AST_CELL, new AstNode(AST_CELLTYPE));
3440 cell->str = prefix.substr(0, GetSize(prefix)-1);
3441 cell->children[0]->str = celltype;
3442
3443 for (auto attr : decl->attributes)
3444 if (attr.first.str().rfind("\\via_celltype_defparam_", 0) == 0)
3445 {
3446 AstNode *cell_arg = new AstNode(AST_PARASET, attr.second->clone());
3447 cell_arg->str = RTLIL::escape_id(attr.first.substr(strlen("\\via_celltype_defparam_")));
3448 cell->children.push_back(cell_arg);
3449 }
3450
3451 for (auto child : decl->children)
3452 if (child->type == AST_WIRE && (child->is_input || child->is_output || (type == AST_FCALL && child->str == str)))
3453 {
3454 AstNode *wire = child->clone();
3455 wire->port_id = 0;
3456 wire->is_input = false;
3457 wire->is_output = false;
3458 current_ast_mod->children.push_back(wire);
3459 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
3460
3461 AstNode *wire_id = new AstNode(AST_IDENTIFIER);
3462 wire_id->str = wire->str;
3463
3464 if ((child->is_input || child->is_output) && arg_count < children.size())
3465 {
3466 AstNode *arg = children[arg_count++]->clone();
3467 AstNode *assign = child->is_input ?
3468 new AstNode(AST_ASSIGN_EQ, wire_id->clone(), arg) :
3469 new AstNode(AST_ASSIGN_EQ, arg, wire_id->clone());
3470 assign->children[0]->was_checked = true;
3471
3472 for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) {
3473 if (*it != current_block_child)
3474 continue;
3475 current_block->children.insert(it, assign);
3476 break;
3477 }
3478 }
3479
3480 AstNode *cell_arg = new AstNode(AST_ARGUMENT, wire_id);
3481 cell_arg->str = child->str == str ? outport : child->str;
3482 cell->children.push_back(cell_arg);
3483 }
3484
3485 current_ast_mod->children.push_back(cell);
3486 goto replace_fcall_with_id;
3487 }
3488
3489 for (auto child : decl->children)
3490 if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM || child->type == AST_ENUM_ITEM)
3491 {
3492 AstNode *wire = nullptr;
3493
3494 if (wire_cache.count(child->str))
3495 {
3496 wire = wire_cache.at(child->str);
3497 bool contains_value = wire->type == AST_LOCALPARAM;
3498 if (wire->children.size() == contains_value) {
3499 for (auto c : child->children)
3500 wire->children.push_back(c->clone());
3501 } else if (!child->children.empty()) {
3502 while (child->simplify(true, false, false, stage, -1, false, false)) { }
3503 if (GetSize(child->children) == GetSize(wire->children) - contains_value) {
3504 for (int i = 0; i < GetSize(child->children); i++)
3505 if (*child->children.at(i) != *wire->children.at(i + contains_value))
3506 goto tcall_incompatible_wires;
3507 } else {
3508 tcall_incompatible_wires:
3509 log_file_error(filename, location.first_line, "Incompatible re-declaration of wire %s.\n", child->str.c_str());
3510 }
3511 }
3512 }
3513 else
3514 {
3515 wire = child->clone();
3516 wire->port_id = 0;
3517 wire->is_input = false;
3518 wire->is_output = false;
3519 wire->is_reg = true;
3520 wire->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
3521 if (child->type == AST_ENUM_ITEM)
3522 wire->attributes[ID::enum_base_type] = child->attributes[ID::enum_base_type];
3523
3524 wire_cache[child->str] = wire;
3525
3526 current_scope[wire->str] = wire;
3527 current_ast_mod->children.push_back(wire);
3528 }
3529
3530 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
3531
3532 if ((child->is_input || child->is_output) && arg_count < children.size())
3533 {
3534 AstNode *arg = children[arg_count++]->clone();
3535 // convert purely constant arguments into localparams
3536 if (child->is_input && child->type == AST_WIRE && arg->type == AST_CONSTANT && node_contains_assignment_to(decl, child)) {
3537 wire->type = AST_LOCALPARAM;
3538 if (wire->attributes.count(ID::nosync))
3539 delete wire->attributes.at(ID::nosync);
3540 wire->attributes.erase(ID::nosync);
3541 wire->children.insert(wire->children.begin(), arg->clone());
3542 // args without a range implicitly have width 1
3543 if (wire->children.back()->type != AST_RANGE) {
3544 // check if this wire is redeclared with an explicit size
3545 bool uses_explicit_size = false;
3546 for (const AstNode *other_child : decl->children)
3547 if (other_child->type == AST_WIRE && child->str == other_child->str
3548 && !other_child->children.empty()
3549 && other_child->children.back()->type == AST_RANGE) {
3550 uses_explicit_size = true;
3551 break;
3552 }
3553 if (!uses_explicit_size) {
3554 AstNode* range = new AstNode();
3555 range->type = AST_RANGE;
3556 wire->children.push_back(range);
3557 range->children.push_back(mkconst_int(0, true));
3558 range->children.push_back(mkconst_int(0, true));
3559 }
3560 }
3561 // updates the sizing
3562 while (wire->simplify(true, false, false, 1, -1, false, false)) { }
3563 delete arg;
3564 continue;
3565 }
3566 AstNode *wire_id = new AstNode(AST_IDENTIFIER);
3567 wire_id->str = wire->str;
3568 AstNode *assign = child->is_input ?
3569 new AstNode(AST_ASSIGN_EQ, wire_id, arg) :
3570 new AstNode(AST_ASSIGN_EQ, arg, wire_id);
3571 assign->children[0]->was_checked = true;
3572 if (child->is_input)
3573 new_stmts.push_back(assign);
3574 else
3575 output_assignments.push_back(assign);
3576 }
3577 }
3578
3579 for (auto child : decl->children)
3580 if (child->type != AST_WIRE && child->type != AST_MEMORY && child->type != AST_PARAMETER && child->type != AST_LOCALPARAM)
3581 new_stmts.push_back(child->clone());
3582
3583 new_stmts.insert(new_stmts.end(), output_assignments.begin(), output_assignments.end());
3584
3585 for (auto it = current_block->children.begin(); ; it++) {
3586 log_assert(it != current_block->children.end());
3587 if (*it == current_block_child) {
3588 current_block->children.insert(it, new_stmts.begin(), new_stmts.end());
3589 break;
3590 }
3591 }
3592
3593 replace_fcall_with_id:
3594 delete decl;
3595 if (type == AST_FCALL) {
3596 delete_children();
3597 type = AST_IDENTIFIER;
3598 str = prefix_id(prefix, "$result");
3599 }
3600 if (type == AST_TCALL)
3601 str = "";
3602 did_something = true;
3603 }
3604
3605 replace_fcall_later:;
3606
3607 // perform const folding when activated
3608 if (const_fold)
3609 {
3610 bool string_op;
3611 std::vector<RTLIL::State> tmp_bits;
3612 RTLIL::Const (*const_func)(const RTLIL::Const&, const RTLIL::Const&, bool, bool, int);
3613 RTLIL::Const dummy_arg;
3614
3615 switch (type)
3616 {
3617 case AST_IDENTIFIER:
3618 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)) {
3619 if (current_scope[str]->children[0]->type == AST_CONSTANT) {
3620 if (children.size() != 0 && children[0]->type == AST_RANGE && children[0]->range_valid) {
3621 std::vector<RTLIL::State> data;
3622 bool param_upto = current_scope[str]->range_valid && current_scope[str]->range_swapped;
3623 int param_offset = current_scope[str]->range_valid ? current_scope[str]->range_right : 0;
3624 int param_width = current_scope[str]->range_valid ? current_scope[str]->range_left - current_scope[str]->range_right + 1 :
3625 GetSize(current_scope[str]->children[0]->bits);
3626 int tmp_range_left = children[0]->range_left, tmp_range_right = children[0]->range_right;
3627 if (param_upto) {
3628 tmp_range_left = (param_width + 2*param_offset) - children[0]->range_right - 1;
3629 tmp_range_right = (param_width + 2*param_offset) - children[0]->range_left - 1;
3630 }
3631 for (int i = tmp_range_right; i <= tmp_range_left; i++) {
3632 int index = i - param_offset;
3633 if (0 <= index && index < param_width)
3634 data.push_back(current_scope[str]->children[0]->bits[index]);
3635 else
3636 data.push_back(RTLIL::State::Sx);
3637 }
3638 newNode = mkconst_bits(data, false);
3639 } else
3640 if (children.size() == 0)
3641 newNode = current_scope[str]->children[0]->clone();
3642 } else
3643 if (current_scope[str]->children[0]->isConst())
3644 newNode = current_scope[str]->children[0]->clone();
3645 }
3646 else if (at_zero && current_scope.count(str) > 0) {
3647 AstNode *node = current_scope[str];
3648 if (node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY)
3649 newNode = mkconst_int(0, sign_hint, width_hint);
3650 }
3651 break;
3652 case AST_MEMRD:
3653 if (at_zero) {
3654 newNode = mkconst_int(0, sign_hint, width_hint);
3655 }
3656 break;
3657 case AST_BIT_NOT:
3658 if (children[0]->type == AST_CONSTANT) {
3659 RTLIL::Const y = RTLIL::const_not(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint);
3660 newNode = mkconst_bits(y.bits, sign_hint);
3661 }
3662 break;
3663 case AST_TO_SIGNED:
3664 case AST_TO_UNSIGNED:
3665 if (children[0]->type == AST_CONSTANT) {
3666 RTLIL::Const y = children[0]->bitsAsConst(width_hint, sign_hint);
3667 newNode = mkconst_bits(y.bits, type == AST_TO_SIGNED);
3668 }
3669 break;
3670 if (0) { case AST_BIT_AND: const_func = RTLIL::const_and; }
3671 if (0) { case AST_BIT_OR: const_func = RTLIL::const_or; }
3672 if (0) { case AST_BIT_XOR: const_func = RTLIL::const_xor; }
3673 if (0) { case AST_BIT_XNOR: const_func = RTLIL::const_xnor; }
3674 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
3675 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
3676 children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint);
3677 newNode = mkconst_bits(y.bits, sign_hint);
3678 }
3679 break;
3680 if (0) { case AST_REDUCE_AND: const_func = RTLIL::const_reduce_and; }
3681 if (0) { case AST_REDUCE_OR: const_func = RTLIL::const_reduce_or; }
3682 if (0) { case AST_REDUCE_XOR: const_func = RTLIL::const_reduce_xor; }
3683 if (0) { case AST_REDUCE_XNOR: const_func = RTLIL::const_reduce_xnor; }
3684 if (0) { case AST_REDUCE_BOOL: const_func = RTLIL::const_reduce_bool; }
3685 if (children[0]->type == AST_CONSTANT) {
3686 RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), dummy_arg, false, false, -1);
3687 newNode = mkconst_bits(y.bits, false);
3688 }
3689 break;
3690 case AST_LOGIC_NOT:
3691 if (children[0]->type == AST_CONSTANT) {
3692 RTLIL::Const y = RTLIL::const_logic_not(RTLIL::Const(children[0]->bits), dummy_arg, children[0]->is_signed, false, -1);
3693 newNode = mkconst_bits(y.bits, false);
3694 } else
3695 if (children[0]->isConst()) {
3696 newNode = mkconst_int(children[0]->asReal(sign_hint) == 0, false, 1);
3697 }
3698 break;
3699 if (0) { case AST_LOGIC_AND: const_func = RTLIL::const_logic_and; }
3700 if (0) { case AST_LOGIC_OR: const_func = RTLIL::const_logic_or; }
3701 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
3702 RTLIL::Const y = const_func(RTLIL::Const(children[0]->bits), RTLIL::Const(children[1]->bits),
3703 children[0]->is_signed, children[1]->is_signed, -1);
3704 newNode = mkconst_bits(y.bits, false);
3705 } else
3706 if (children[0]->isConst() && children[1]->isConst()) {
3707 if (type == AST_LOGIC_AND)
3708 newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) && (children[1]->asReal(sign_hint) != 0), false, 1);
3709 else
3710 newNode = mkconst_int((children[0]->asReal(sign_hint) != 0) || (children[1]->asReal(sign_hint) != 0), false, 1);
3711 }
3712 break;
3713 if (0) { case AST_SHIFT_LEFT: const_func = RTLIL::const_shl; }
3714 if (0) { case AST_SHIFT_RIGHT: const_func = RTLIL::const_shr; }
3715 if (0) { case AST_SHIFT_SLEFT: const_func = RTLIL::const_sshl; }
3716 if (0) { case AST_SHIFT_SRIGHT: const_func = RTLIL::const_sshr; }
3717 if (0) { case AST_POW: const_func = RTLIL::const_pow; }
3718 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
3719 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
3720 RTLIL::Const(children[1]->bits), sign_hint, type == AST_POW ? children[1]->is_signed : false, width_hint);
3721 newNode = mkconst_bits(y.bits, sign_hint);
3722 } else
3723 if (type == AST_POW && children[0]->isConst() && children[1]->isConst()) {
3724 newNode = new AstNode(AST_REALVALUE);
3725 newNode->realvalue = pow(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint));
3726 }
3727 break;
3728 if (0) { case AST_LT: const_func = RTLIL::const_lt; }
3729 if (0) { case AST_LE: const_func = RTLIL::const_le; }
3730 if (0) { case AST_EQ: const_func = RTLIL::const_eq; }
3731 if (0) { case AST_NE: const_func = RTLIL::const_ne; }
3732 if (0) { case AST_EQX: const_func = RTLIL::const_eqx; }
3733 if (0) { case AST_NEX: const_func = RTLIL::const_nex; }
3734 if (0) { case AST_GE: const_func = RTLIL::const_ge; }
3735 if (0) { case AST_GT: const_func = RTLIL::const_gt; }
3736 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
3737 int cmp_width = max(children[0]->bits.size(), children[1]->bits.size());
3738 bool cmp_signed = children[0]->is_signed && children[1]->is_signed;
3739 RTLIL::Const y = const_func(children[0]->bitsAsConst(cmp_width, cmp_signed),
3740 children[1]->bitsAsConst(cmp_width, cmp_signed), cmp_signed, cmp_signed, 1);
3741 newNode = mkconst_bits(y.bits, false);
3742 } else
3743 if (children[0]->isConst() && children[1]->isConst()) {
3744 bool cmp_signed = (children[0]->type == AST_REALVALUE || children[0]->is_signed) && (children[1]->type == AST_REALVALUE || children[1]->is_signed);
3745 switch (type) {
3746 case AST_LT: newNode = mkconst_int(children[0]->asReal(cmp_signed) < children[1]->asReal(cmp_signed), false, 1); break;
3747 case AST_LE: newNode = mkconst_int(children[0]->asReal(cmp_signed) <= children[1]->asReal(cmp_signed), false, 1); break;
3748 case AST_EQ: newNode = mkconst_int(children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break;
3749 case AST_NE: newNode = mkconst_int(children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break;
3750 case AST_EQX: newNode = mkconst_int(children[0]->asReal(cmp_signed) == children[1]->asReal(cmp_signed), false, 1); break;
3751 case AST_NEX: newNode = mkconst_int(children[0]->asReal(cmp_signed) != children[1]->asReal(cmp_signed), false, 1); break;
3752 case AST_GE: newNode = mkconst_int(children[0]->asReal(cmp_signed) >= children[1]->asReal(cmp_signed), false, 1); break;
3753 case AST_GT: newNode = mkconst_int(children[0]->asReal(cmp_signed) > children[1]->asReal(cmp_signed), false, 1); break;
3754 default: log_abort();
3755 }
3756 }
3757 break;
3758 if (0) { case AST_ADD: const_func = RTLIL::const_add; }
3759 if (0) { case AST_SUB: const_func = RTLIL::const_sub; }
3760 if (0) { case AST_MUL: const_func = RTLIL::const_mul; }
3761 if (0) { case AST_DIV: const_func = RTLIL::const_div; }
3762 if (0) { case AST_MOD: const_func = RTLIL::const_mod; }
3763 if (children[0]->type == AST_CONSTANT && children[1]->type == AST_CONSTANT) {
3764 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint),
3765 children[1]->bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint);
3766 newNode = mkconst_bits(y.bits, sign_hint);
3767 } else
3768 if (children[0]->isConst() && children[1]->isConst()) {
3769 newNode = new AstNode(AST_REALVALUE);
3770 switch (type) {
3771 case AST_ADD: newNode->realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint); break;
3772 case AST_SUB: newNode->realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint); break;
3773 case AST_MUL: newNode->realvalue = children[0]->asReal(sign_hint) * children[1]->asReal(sign_hint); break;
3774 case AST_DIV: newNode->realvalue = children[0]->asReal(sign_hint) / children[1]->asReal(sign_hint); break;
3775 case AST_MOD: newNode->realvalue = fmod(children[0]->asReal(sign_hint), children[1]->asReal(sign_hint)); break;
3776 default: log_abort();
3777 }
3778 }
3779 break;
3780 if (0) { case AST_SELFSZ: const_func = RTLIL::const_pos; }
3781 if (0) { case AST_POS: const_func = RTLIL::const_pos; }
3782 if (0) { case AST_NEG: const_func = RTLIL::const_neg; }
3783 if (children[0]->type == AST_CONSTANT) {
3784 RTLIL::Const y = const_func(children[0]->bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint, false, width_hint);
3785 newNode = mkconst_bits(y.bits, sign_hint);
3786 } else
3787 if (children[0]->isConst()) {
3788 newNode = new AstNode(AST_REALVALUE);
3789 if (type == AST_NEG)
3790 newNode->realvalue = -children[0]->asReal(sign_hint);
3791 else
3792 newNode->realvalue = +children[0]->asReal(sign_hint);
3793 }
3794 break;
3795 case AST_TERNARY:
3796 if (children[0]->isConst())
3797 {
3798 auto pair = get_tern_choice();
3799 AstNode *choice = pair.first;
3800 AstNode *not_choice = pair.second;
3801
3802 if (choice != NULL) {
3803 if (choice->type == AST_CONSTANT) {
3804 int other_width_hint = width_hint;
3805 bool other_sign_hint = sign_hint, other_real = false;
3806 not_choice->detectSignWidth(other_width_hint, other_sign_hint, &other_real);
3807 if (other_real) {
3808 newNode = new AstNode(AST_REALVALUE);
3809 choice->detectSignWidth(width_hint, sign_hint);
3810 newNode->realvalue = choice->asReal(sign_hint);
3811 } else {
3812 RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint);
3813 if (choice->is_string && y.bits.size() % 8 == 0 && sign_hint == false)
3814 newNode = mkconst_str(y.bits);
3815 else
3816 newNode = mkconst_bits(y.bits, sign_hint);
3817 }
3818 } else
3819 if (choice->isConst()) {
3820 newNode = choice->clone();
3821 }
3822 } else if (children[1]->type == AST_CONSTANT && children[2]->type == AST_CONSTANT) {
3823 RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint);
3824 RTLIL::Const b = children[2]->bitsAsConst(width_hint, sign_hint);
3825 log_assert(a.bits.size() == b.bits.size());
3826 for (size_t i = 0; i < a.bits.size(); i++)
3827 if (a.bits[i] != b.bits[i])
3828 a.bits[i] = RTLIL::State::Sx;
3829 newNode = mkconst_bits(a.bits, sign_hint);
3830 } else if (children[1]->isConst() && children[2]->isConst()) {
3831 newNode = new AstNode(AST_REALVALUE);
3832 if (children[1]->asReal(sign_hint) == children[2]->asReal(sign_hint))
3833 newNode->realvalue = children[1]->asReal(sign_hint);
3834 else
3835 // IEEE Std 1800-2012 Sec. 11.4.11 states that the entry in Table 7-1 for
3836 // the data type in question should be returned if the ?: is ambiguous. The
3837 // value in Table 7-1 for the 'real' type is 0.0.
3838 newNode->realvalue = 0.0;
3839 }
3840 }
3841 break;
3842 case AST_CAST_SIZE:
3843 if (children.at(0)->type == AST_CONSTANT && children.at(1)->type == AST_CONSTANT) {
3844 int width = children[0]->bitsAsConst().as_int();
3845 RTLIL::Const val;
3846 if (children[1]->is_unsized)
3847 val = children[1]->bitsAsUnsizedConst(width);
3848 else
3849 val = children[1]->bitsAsConst(width);
3850 newNode = mkconst_bits(val.bits, children[1]->is_signed);
3851 }
3852 break;
3853 case AST_CONCAT:
3854 string_op = !children.empty();
3855 for (auto it = children.begin(); it != children.end(); it++) {
3856 if ((*it)->type != AST_CONSTANT)
3857 goto not_const;
3858 if (!(*it)->is_string)
3859 string_op = false;
3860 tmp_bits.insert(tmp_bits.end(), (*it)->bits.begin(), (*it)->bits.end());
3861 }
3862 newNode = string_op ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false);
3863 break;
3864 case AST_REPLICATE:
3865 if (children.at(0)->type != AST_CONSTANT || children.at(1)->type != AST_CONSTANT)
3866 goto not_const;
3867 for (int i = 0; i < children[0]->bitsAsConst().as_int(); i++)
3868 tmp_bits.insert(tmp_bits.end(), children.at(1)->bits.begin(), children.at(1)->bits.end());
3869 newNode = children.at(1)->is_string ? mkconst_str(tmp_bits) : mkconst_bits(tmp_bits, false);
3870 break;
3871 default:
3872 not_const:
3873 break;
3874 }
3875 }
3876
3877 // if any of the above set 'newNode' -> use 'newNode' as template to update 'this'
3878 if (newNode) {
3879 apply_newNode:
3880 // fprintf(stderr, "----\n");
3881 // dumpAst(stderr, "- ");
3882 // newNode->dumpAst(stderr, "+ ");
3883 log_assert(newNode != NULL);
3884 newNode->filename = filename;
3885 newNode->location = location;
3886 newNode->cloneInto(this);
3887 delete newNode;
3888 did_something = true;
3889 }
3890
3891 if (!did_something)
3892 basic_prep = true;
3893
3894 recursion_counter--;
3895 return did_something;
3896 }
3897
3898 void AstNode::replace_result_wire_name_in_function(const std::string &from, const std::string &to)
3899 {
3900 for (AstNode *child : children)
3901 child->replace_result_wire_name_in_function(from, to);
3902 if (str == from && type != AST_FCALL && type != AST_TCALL)
3903 str = to;
3904 }
3905
3906 // replace a readmem[bh] TCALL ast node with a block of memory assignments
3907 AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init)
3908 {
3909 int mem_width, mem_size, addr_bits;
3910 memory->meminfo(mem_width, mem_size, addr_bits);
3911
3912 AstNode *block = new AstNode(AST_BLOCK);
3913
3914 AstNode *meminit = nullptr;
3915 int next_meminit_cursor=0;
3916 vector<State> meminit_bits;
3917 vector<State> en_bits;
3918 int meminit_size=0;
3919
3920 for (int i = 0; i < mem_width; i++)
3921 en_bits.push_back(State::S1);
3922
3923 std::ifstream f;
3924 f.open(mem_filename.c_str());
3925 if (f.fail()) {
3926 #ifdef _WIN32
3927 char slash = '\\';
3928 #else
3929 char slash = '/';
3930 #endif
3931 std::string path = filename.substr(0, filename.find_last_of(slash)+1);
3932 f.open(path + mem_filename.c_str());
3933 yosys_input_files.insert(path + mem_filename);
3934 } else {
3935 yosys_input_files.insert(mem_filename);
3936 }
3937 if (f.fail() || GetSize(mem_filename) == 0)
3938 log_file_error(filename, location.first_line, "Can not open file `%s` for %s.\n", mem_filename.c_str(), str.c_str());
3939
3940 log_assert(GetSize(memory->children) == 2 && memory->children[1]->type == AST_RANGE && memory->children[1]->range_valid);
3941 int range_left = memory->children[1]->range_left, range_right = memory->children[1]->range_right;
3942 int range_min = min(range_left, range_right), range_max = max(range_left, range_right);
3943
3944 if (start_addr < 0)
3945 start_addr = range_min;
3946
3947 if (finish_addr < 0)
3948 finish_addr = range_max + 1;
3949
3950 bool in_comment = false;
3951 int increment = start_addr <= finish_addr ? +1 : -1;
3952 int cursor = start_addr;
3953
3954 while (!f.eof())
3955 {
3956 std::string line, token;
3957 std::getline(f, line);
3958
3959 for (int i = 0; i < GetSize(line); i++) {
3960 if (in_comment && line.compare(i, 2, "*/") == 0) {
3961 line[i] = ' ';
3962 line[i+1] = ' ';
3963 in_comment = false;
3964 continue;
3965 }
3966 if (!in_comment && line.compare(i, 2, "/*") == 0)
3967 in_comment = true;
3968 if (in_comment)
3969 line[i] = ' ';
3970 }
3971
3972 while (1)
3973 {
3974 token = next_token(line, " \t\r\n");
3975 if (token.empty() || token.compare(0, 2, "//") == 0)
3976 break;
3977
3978 if (token[0] == '@') {
3979 token = token.substr(1);
3980 const char *nptr = token.c_str();
3981 char *endptr;
3982 cursor = strtol(nptr, &endptr, 16);
3983 if (!*nptr || *endptr)
3984 log_file_error(filename, location.first_line, "Can not parse address `%s` for %s.\n", nptr, str.c_str());
3985 continue;
3986 }
3987
3988 AstNode *value = VERILOG_FRONTEND::const2ast(stringf("%d'%c", mem_width, is_readmemh ? 'h' : 'b') + token);
3989
3990 if (unconditional_init)
3991 {
3992 if (meminit == nullptr || cursor != next_meminit_cursor)
3993 {
3994 if (meminit != nullptr) {
3995 meminit->children[1] = AstNode::mkconst_bits(meminit_bits, false);
3996 meminit->children[3] = AstNode::mkconst_int(meminit_size, false);
3997 }
3998
3999 meminit = new AstNode(AST_MEMINIT);
4000 meminit->children.push_back(AstNode::mkconst_int(cursor, false));
4001 meminit->children.push_back(nullptr);
4002 meminit->children.push_back(AstNode::mkconst_bits(en_bits, false));
4003 meminit->children.push_back(nullptr);
4004 meminit->str = memory->str;
4005 meminit->id2ast = memory;
4006 meminit_bits.clear();
4007 meminit_size = 0;
4008
4009 current_ast_mod->children.push_back(meminit);
4010 next_meminit_cursor = cursor;
4011 }
4012
4013 meminit_size++;
4014 next_meminit_cursor++;
4015 meminit_bits.insert(meminit_bits.end(), value->bits.begin(), value->bits.end());
4016 delete value;
4017 }
4018 else
4019 {
4020 block->children.push_back(new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER, new AstNode(AST_RANGE, AstNode::mkconst_int(cursor, false))), value));
4021 block->children.back()->children[0]->str = memory->str;
4022 block->children.back()->children[0]->id2ast = memory;
4023 block->children.back()->children[0]->was_checked = true;
4024 }
4025
4026 cursor += increment;
4027 if ((cursor == finish_addr+increment) || (increment > 0 && cursor > range_max) || (increment < 0 && cursor < range_min))
4028 break;
4029 }
4030
4031 if ((cursor == finish_addr+increment) || (increment > 0 && cursor > range_max) || (increment < 0 && cursor < range_min))
4032 break;
4033 }
4034
4035 if (meminit != nullptr) {
4036 meminit->children[1] = AstNode::mkconst_bits(meminit_bits, false);
4037 meminit->children[3] = AstNode::mkconst_int(meminit_size, false);
4038 }
4039
4040 return block;
4041 }
4042
4043 // annotate the names of all wires and other named objects in a named generate
4044 // or procedural block; nested blocks are themselves annotated such that the
4045 // prefix is carried forward, but resolution of their children is deferred
4046 void AstNode::expand_genblock(const std::string &prefix)
4047 {
4048 if (type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL || type == AST_WIRETYPE || type == AST_PREFIX) {
4049 log_assert(!str.empty());
4050
4051 // search starting in the innermost scope and then stepping outward
4052 for (size_t ppos = prefix.size() - 1; ppos; --ppos) {
4053 if (prefix.at(ppos) != '.') continue;
4054
4055 std::string new_prefix = prefix.substr(0, ppos + 1);
4056 auto attempt_resolve = [&new_prefix](const std::string &ident) -> std::string {
4057 std::string new_name = prefix_id(new_prefix, ident);
4058 if (current_scope.count(new_name))
4059 return new_name;
4060 return {};
4061 };
4062
4063 // attempt to resolve the full identifier
4064 std::string resolved = attempt_resolve(str);
4065 if (!resolved.empty()) {
4066 str = resolved;
4067 break;
4068 }
4069
4070 // attempt to resolve hierarchical prefixes within the identifier,
4071 // as the prefix could refer to a local scope which exists but
4072 // hasn't yet been elaborated
4073 for (size_t spos = str.size() - 1; spos; --spos) {
4074 if (str.at(spos) != '.') continue;
4075 resolved = attempt_resolve(str.substr(0, spos));
4076 if (!resolved.empty()) {
4077 str = resolved + str.substr(spos);
4078 ppos = 1; // break outer loop
4079 break;
4080 }
4081 }
4082
4083 }
4084 }
4085
4086 auto prefix_node = [&prefix](AstNode* child) {
4087 if (child->str.empty()) return;
4088 std::string new_name = prefix_id(prefix, child->str);
4089 if (child->type == AST_FUNCTION)
4090 child->replace_result_wire_name_in_function(child->str, new_name);
4091 else
4092 child->str = new_name;
4093 current_scope[new_name] = child;
4094 };
4095
4096 for (size_t i = 0; i < children.size(); i++) {
4097 AstNode *child = children[i];
4098
4099 switch (child->type) {
4100 case AST_WIRE:
4101 case AST_MEMORY:
4102 case AST_PARAMETER:
4103 case AST_LOCALPARAM:
4104 case AST_FUNCTION:
4105 case AST_TASK:
4106 case AST_CELL:
4107 case AST_TYPEDEF:
4108 case AST_ENUM_ITEM:
4109 case AST_GENVAR:
4110 prefix_node(child);
4111 break;
4112
4113 case AST_BLOCK:
4114 case AST_GENBLOCK:
4115 if (!child->str.empty())
4116 prefix_node(child);
4117 break;
4118
4119 case AST_ENUM:
4120 current_scope[child->str] = child;
4121 for (auto enode : child->children){
4122 log_assert(enode->type == AST_ENUM_ITEM);
4123 prefix_node(enode);
4124 }
4125 break;
4126
4127 default:
4128 break;
4129 }
4130 }
4131
4132 for (size_t i = 0; i < children.size(); i++) {
4133 AstNode *child = children[i];
4134 // AST_PREFIX member names should not be prefixed; we recurse into them
4135 // as normal to ensure indices and ranges are properly resolved, and
4136 // then restore the previous string
4137 if (type == AST_PREFIX && i == 1) {
4138 std::string backup_scope_name = child->str;
4139 child->expand_genblock(prefix);
4140 child->str = backup_scope_name;
4141 continue;
4142 }
4143 // functions/tasks may reference wires, constants, etc. in this scope
4144 if (child->type == AST_FUNCTION || child->type == AST_TASK)
4145 continue;
4146 // named blocks pick up the current prefix and will expanded later
4147 if ((child->type == AST_GENBLOCK || child->type == AST_BLOCK) && !child->str.empty())
4148 continue;
4149
4150 child->expand_genblock(prefix);
4151 }
4152 }
4153
4154 // add implicit AST_GENBLOCK names according to IEEE 1364-2005 Section 12.4.3 or
4155 // IEEE 1800-2017 Section 27.6
4156 void AstNode::label_genblks(std::set<std::string>& existing, int &counter)
4157 {
4158 switch (type) {
4159 case AST_GENIF:
4160 case AST_GENFOR:
4161 case AST_GENCASE:
4162 // seeing a proper generate control flow construct increments the
4163 // counter once
4164 ++counter;
4165 for (AstNode *child : children)
4166 child->label_genblks(existing, counter);
4167 break;
4168
4169 case AST_GENBLOCK: {
4170 // if this block is unlabeled, generate its corresponding unique name
4171 for (int padding = 0; str.empty(); ++padding) {
4172 std::string candidate = "\\genblk";
4173 for (int i = 0; i < padding; ++i)
4174 candidate += '0';
4175 candidate += std::to_string(counter);
4176 if (!existing.count(candidate))
4177 str = candidate;
4178 }
4179 // within a genblk, the counter starts fresh
4180 std::set<std::string> existing_local = existing;
4181 int counter_local = 0;
4182 for (AstNode *child : children)
4183 child->label_genblks(existing_local, counter_local);
4184 break;
4185 }
4186
4187 default:
4188 // track names which could conflict with implicit genblk names
4189 if (str.rfind("\\genblk", 0) == 0)
4190 existing.insert(str);
4191 for (AstNode *child : children)
4192 child->label_genblks(existing, counter);
4193 break;
4194 }
4195 }
4196
4197 // helper function for mem2reg_as_needed_pass1
4198 static void mark_memories_assign_lhs_complex(dict<AstNode*, pool<std::string>> &mem2reg_places,
4199 dict<AstNode*, uint32_t> &mem2reg_candidates, AstNode *that)
4200 {
4201 for (auto &child : that->children)
4202 mark_memories_assign_lhs_complex(mem2reg_places, mem2reg_candidates, child);
4203
4204 if (that->type == AST_IDENTIFIER && that->id2ast && that->id2ast->type == AST_MEMORY) {
4205 AstNode *mem = that->id2ast;
4206 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_CMPLX_LHS))
4207 mem2reg_places[mem].insert(stringf("%s:%d", that->filename.c_str(), that->location.first_line));
4208 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CMPLX_LHS;
4209 }
4210 }
4211
4212 // find memories that should be replaced by registers
4213 void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg_places,
4214 dict<AstNode*, uint32_t> &mem2reg_candidates, dict<AstNode*, uint32_t> &proc_flags, uint32_t &flags)
4215 {
4216 uint32_t children_flags = 0;
4217 int lhs_children_counter = 0;
4218
4219 if (type == AST_TYPEDEF)
4220 return; // don't touch content of typedefs
4221
4222 if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ)
4223 {
4224 // mark all memories that are used in a complex expression on the left side of an assignment
4225 for (auto &lhs_child : children[0]->children)
4226 mark_memories_assign_lhs_complex(mem2reg_places, mem2reg_candidates, lhs_child);
4227
4228 if (children[0]->type == AST_IDENTIFIER && children[0]->id2ast && children[0]->id2ast->type == AST_MEMORY)
4229 {
4230 AstNode *mem = children[0]->id2ast;
4231
4232 // activate mem2reg if this is assigned in an async proc
4233 if (flags & AstNode::MEM2REG_FL_ASYNC) {
4234 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ASYNC))
4235 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line));
4236 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ASYNC;
4237 }
4238
4239 // remember if this is assigned blocking (=)
4240 if (type == AST_ASSIGN_EQ) {
4241 if (!(proc_flags[mem] & AstNode::MEM2REG_FL_EQ1))
4242 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line));
4243 proc_flags[mem] |= AstNode::MEM2REG_FL_EQ1;
4244 }
4245
4246 // for proper (non-init) writes: remember if this is a constant index or not
4247 if ((flags & MEM2REG_FL_INIT) == 0) {
4248 if (children[0]->children.size() && children[0]->children[0]->type == AST_RANGE && children[0]->children[0]->children.size()) {
4249 if (children[0]->children[0]->children[0]->type == AST_CONSTANT)
4250 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CONST_LHS;
4251 else
4252 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_VAR_LHS;
4253 }
4254 }
4255
4256 // remember where this is
4257 if (flags & MEM2REG_FL_INIT) {
4258 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_INIT))
4259 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line));
4260 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_INIT;
4261 } else {
4262 if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_ELSE))
4263 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line));
4264 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_SET_ELSE;
4265 }
4266 }
4267
4268 lhs_children_counter = 1;
4269 }
4270
4271 if (type == AST_IDENTIFIER && id2ast && id2ast->type == AST_MEMORY)
4272 {
4273 AstNode *mem = id2ast;
4274
4275 // flag if used after blocking assignment (in same proc)
4276 if ((proc_flags[mem] & AstNode::MEM2REG_FL_EQ1) && !(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_EQ2)) {
4277 mem2reg_places[mem].insert(stringf("%s:%d", filename.c_str(), location.first_line));
4278 mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_EQ2;
4279 }
4280 }
4281
4282 // also activate if requested, either by using mem2reg attribute or by declaring array as 'wire' instead of 'reg' or 'logic'
4283 if (type == AST_MEMORY && (get_bool_attribute(ID::mem2reg) || (flags & AstNode::MEM2REG_FL_ALL) || !(is_reg || is_logic)))
4284 mem2reg_candidates[this] |= AstNode::MEM2REG_FL_FORCED;
4285
4286 if (type == AST_MODULE && get_bool_attribute(ID::mem2reg))
4287 children_flags |= AstNode::MEM2REG_FL_ALL;
4288
4289 dict<AstNode*, uint32_t> *proc_flags_p = NULL;
4290
4291 if (type == AST_ALWAYS) {
4292 int count_edge_events = 0;
4293 for (auto child : children)
4294 if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE)
4295 count_edge_events++;
4296 if (count_edge_events != 1)
4297 children_flags |= AstNode::MEM2REG_FL_ASYNC;
4298 proc_flags_p = new dict<AstNode*, uint32_t>;
4299 }
4300
4301 if (type == AST_INITIAL) {
4302 children_flags |= AstNode::MEM2REG_FL_INIT;
4303 proc_flags_p = new dict<AstNode*, uint32_t>;
4304 }
4305
4306 uint32_t backup_flags = flags;
4307 flags |= children_flags;
4308 log_assert((flags & ~0x000000ff) == 0);
4309
4310 for (auto child : children)
4311 {
4312 if (lhs_children_counter > 0) {
4313 lhs_children_counter--;
4314 if (child->children.size() && child->children[0]->type == AST_RANGE && child->children[0]->children.size()) {
4315 for (auto c : child->children[0]->children) {
4316 if (proc_flags_p)
4317 c->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, *proc_flags_p, flags);
4318 else
4319 c->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, proc_flags, flags);
4320 }
4321 }
4322 } else
4323 if (proc_flags_p)
4324 child->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, *proc_flags_p, flags);
4325 else
4326 child->mem2reg_as_needed_pass1(mem2reg_places, mem2reg_candidates, proc_flags, flags);
4327 }
4328
4329 flags &= ~children_flags | backup_flags;
4330
4331 if (proc_flags_p) {
4332 #ifndef NDEBUG
4333 for (auto it : *proc_flags_p)
4334 log_assert((it.second & ~0xff000000) == 0);
4335 #endif
4336 delete proc_flags_p;
4337 }
4338 }
4339
4340 bool AstNode::mem2reg_check(pool<AstNode*> &mem2reg_set)
4341 {
4342 if (type != AST_IDENTIFIER || !id2ast || !mem2reg_set.count(id2ast))
4343 return false;
4344
4345 if (children.empty() || children[0]->type != AST_RANGE || GetSize(children[0]->children) != 1)
4346 log_file_error(filename, location.first_line, "Invalid array access.\n");
4347
4348 return true;
4349 }
4350
4351 void AstNode::mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes)
4352 {
4353 log_assert(mem2reg_set.count(this) == 0);
4354
4355 if (mem2reg_set.count(id2ast))
4356 id2ast = nullptr;
4357
4358 for (size_t i = 0; i < children.size(); i++) {
4359 if (mem2reg_set.count(children[i]) > 0) {
4360 delnodes.push_back(children[i]);
4361 children.erase(children.begin() + (i--));
4362 } else {
4363 children[i]->mem2reg_remove(mem2reg_set, delnodes);
4364 }
4365 }
4366 }
4367
4368 // actually replace memories with registers
4369 bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block, AstNode *&async_block)
4370 {
4371 bool did_something = false;
4372
4373 if (type == AST_BLOCK)
4374 block = this;
4375
4376 if (type == AST_FUNCTION || type == AST_TASK)
4377 return false;
4378
4379 if (type == AST_TYPEDEF)
4380 return false;
4381
4382 if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast))
4383 {
4384 log_assert(children[0]->type == AST_CONSTANT);
4385 log_assert(children[1]->type == AST_CONSTANT);
4386 log_assert(children[2]->type == AST_CONSTANT);
4387 log_assert(children[3]->type == AST_CONSTANT);
4388
4389 int cursor = children[0]->asInt(false);
4390 Const data = children[1]->bitsAsConst();
4391 Const en = children[2]->bitsAsConst();
4392 int length = children[3]->asInt(false);
4393
4394 if (length != 0)
4395 {
4396 AstNode *block = new AstNode(AST_INITIAL, new AstNode(AST_BLOCK));
4397 mod->children.push_back(block);
4398 block = block->children[0];
4399
4400 int wordsz = GetSize(data) / length;
4401
4402 for (int i = 0; i < length; i++) {
4403 int pos = 0;
4404 while (pos < wordsz) {
4405 if (en[pos] != State::S1) {
4406 pos++;
4407 } else {
4408 int epos = pos + 1;
4409 while (epos < wordsz && en[epos] == State::S1)
4410 epos++;
4411 int clen = epos - pos;
4412 AstNode *range = new AstNode(AST_RANGE, AstNode::mkconst_int(cursor+i, false));
4413 if (pos != 0 || epos != wordsz) {
4414 int left;
4415 int right;
4416 AstNode *mrange = id2ast->children[0];
4417 if (mrange->range_left < mrange->range_right) {
4418 right = mrange->range_right - pos;
4419 left = mrange->range_right - epos + 1;
4420 } else {
4421 right = mrange->range_right + pos;
4422 left = mrange->range_right + epos - 1;
4423 }
4424 range = new AstNode(AST_MULTIRANGE, range, new AstNode(AST_RANGE, AstNode::mkconst_int(left, true), AstNode::mkconst_int(right, true)));
4425 }
4426 AstNode *target = new AstNode(AST_IDENTIFIER, range);
4427 target->str = str;
4428 target->id2ast = id2ast;
4429 target->was_checked = true;
4430 block->children.push_back(new AstNode(AST_ASSIGN_EQ, target, mkconst_bits(data.extract(i*wordsz + pos, clen).bits, false)));
4431 pos = epos;
4432 }
4433 }
4434 }
4435 }
4436
4437 AstNode *newNode = new AstNode(AST_NONE);
4438 newNode->cloneInto(this);
4439 delete newNode;
4440
4441 did_something = true;
4442 }
4443
4444 if (type == AST_ASSIGN && block == NULL && children[0]->mem2reg_check(mem2reg_set))
4445 {
4446 if (async_block == NULL) {
4447 async_block = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
4448 mod->children.push_back(async_block);
4449 }
4450
4451 AstNode *newNode = clone();
4452 newNode->type = AST_ASSIGN_EQ;
4453 newNode->children[0]->was_checked = true;
4454 async_block->children[0]->children.push_back(newNode);
4455
4456 newNode = new AstNode(AST_NONE);
4457 newNode->cloneInto(this);
4458 delete newNode;
4459
4460 did_something = true;
4461 }
4462
4463 if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && children[0]->mem2reg_check(mem2reg_set) &&
4464 children[0]->children[0]->children[0]->type != AST_CONSTANT)
4465 {
4466 std::stringstream sstr;
4467 sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
4468 std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
4469
4470 int mem_width, mem_size, addr_bits;
4471 bool mem_signed = children[0]->id2ast->is_signed;
4472 children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
4473
4474 AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
4475 wire_addr->str = id_addr;
4476 wire_addr->is_reg = true;
4477 wire_addr->was_checked = true;
4478 wire_addr->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
4479 mod->children.push_back(wire_addr);
4480 while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
4481
4482 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
4483 wire_data->str = id_data;
4484 wire_data->is_reg = true;
4485 wire_data->was_checked = true;
4486 wire_data->is_signed = mem_signed;
4487 wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
4488 mod->children.push_back(wire_data);
4489 while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
4490
4491 log_assert(block != NULL);
4492 size_t assign_idx = 0;
4493 while (assign_idx < block->children.size() && block->children[assign_idx] != this)
4494 assign_idx++;
4495 log_assert(assign_idx < block->children.size());
4496
4497 AstNode *assign_addr = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), children[0]->children[0]->children[0]->clone());
4498 assign_addr->children[0]->str = id_addr;
4499 assign_addr->children[0]->was_checked = true;
4500 block->children.insert(block->children.begin()+assign_idx+1, assign_addr);
4501
4502 AstNode *case_node = new AstNode(AST_CASE, new AstNode(AST_IDENTIFIER));
4503 case_node->children[0]->str = id_addr;
4504 for (int i = 0; i < mem_size; i++) {
4505 if (children[0]->children[0]->children[0]->type == AST_CONSTANT && int(children[0]->children[0]->children[0]->integer) != i)
4506 continue;
4507 AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK));
4508 AstNode *assign_reg = new AstNode(type, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER));
4509 if (children[0]->children.size() == 2)
4510 assign_reg->children[0]->children.push_back(children[0]->children[1]->clone());
4511 assign_reg->children[0]->str = stringf("%s[%d]", children[0]->str.c_str(), i);
4512 assign_reg->children[1]->str = id_data;
4513 cond_node->children[1]->children.push_back(assign_reg);
4514 case_node->children.push_back(cond_node);
4515 }
4516 block->children.insert(block->children.begin()+assign_idx+2, case_node);
4517
4518 children[0]->delete_children();
4519 children[0]->range_valid = false;
4520 children[0]->id2ast = NULL;
4521 children[0]->str = id_data;
4522 type = AST_ASSIGN_EQ;
4523 children[0]->was_checked = true;
4524
4525 did_something = true;
4526 }
4527
4528 if (mem2reg_check(mem2reg_set))
4529 {
4530 AstNode *bit_part_sel = NULL;
4531 if (children.size() == 2)
4532 bit_part_sel = children[1]->clone();
4533
4534 if (children[0]->children[0]->type == AST_CONSTANT)
4535 {
4536 int id = children[0]->children[0]->integer;
4537 int left = id2ast->children[1]->children[0]->integer;
4538 int right = id2ast->children[1]->children[1]->integer;
4539 bool valid_const_access =
4540 (left <= id && id <= right) ||
4541 (right <= id && id <= left);
4542 if (valid_const_access)
4543 {
4544 str = stringf("%s[%d]", str.c_str(), id);
4545 delete_children();
4546 range_valid = false;
4547 id2ast = NULL;
4548 }
4549 else
4550 {
4551 int width;
4552 if (bit_part_sel)
4553 {
4554 bit_part_sel->dumpAst(nullptr, "? ");
4555 if (bit_part_sel->children.size() == 1)
4556 width = 0;
4557 else
4558 width = bit_part_sel->children[0]->integer -
4559 bit_part_sel->children[1]->integer;
4560 delete bit_part_sel;
4561 bit_part_sel = nullptr;
4562 }
4563 else
4564 {
4565 width = id2ast->children[0]->children[0]->integer -
4566 id2ast->children[0]->children[1]->integer;
4567 }
4568 width = abs(width) + 1;
4569
4570 delete_children();
4571
4572 std::vector<RTLIL::State> x_bits;
4573 for (int i = 0; i < width; i++)
4574 x_bits.push_back(RTLIL::State::Sx);
4575 AstNode *constant = AstNode::mkconst_bits(x_bits, false);
4576 constant->cloneInto(this);
4577 delete constant;
4578 }
4579 }
4580 else
4581 {
4582 std::stringstream sstr;
4583 sstr << "$mem2reg_rd$" << str << "$" << filename << ":" << location.first_line << "$" << (autoidx++);
4584 std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
4585
4586 int mem_width, mem_size, addr_bits;
4587 bool mem_signed = id2ast->is_signed;
4588 id2ast->meminfo(mem_width, mem_size, addr_bits);
4589
4590 AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
4591 wire_addr->str = id_addr;
4592 wire_addr->is_reg = true;
4593 wire_addr->was_checked = true;
4594 if (block)
4595 wire_addr->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
4596 mod->children.push_back(wire_addr);
4597 while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { }
4598
4599 AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
4600 wire_data->str = id_data;
4601 wire_data->is_reg = true;
4602 wire_data->was_checked = true;
4603 wire_data->is_signed = mem_signed;
4604 if (block)
4605 wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false);
4606 mod->children.push_back(wire_data);
4607 while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
4608
4609 AstNode *assign_addr = new AstNode(block ? AST_ASSIGN_EQ : AST_ASSIGN, new AstNode(AST_IDENTIFIER), children[0]->children[0]->clone());
4610 assign_addr->children[0]->str = id_addr;
4611 assign_addr->children[0]->was_checked = true;
4612
4613 AstNode *case_node = new AstNode(AST_CASE, new AstNode(AST_IDENTIFIER));
4614 case_node->children[0]->str = id_addr;
4615
4616 for (int i = 0; i < mem_size; i++) {
4617 if (children[0]->children[0]->type == AST_CONSTANT && int(children[0]->children[0]->integer) != i)
4618 continue;
4619 AstNode *cond_node = new AstNode(AST_COND, AstNode::mkconst_int(i, false, addr_bits), new AstNode(AST_BLOCK));
4620 AstNode *assign_reg = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), new AstNode(AST_IDENTIFIER));
4621 assign_reg->children[0]->str = id_data;
4622 assign_reg->children[0]->was_checked = true;
4623 assign_reg->children[1]->str = stringf("%s[%d]", str.c_str(), i);
4624 cond_node->children[1]->children.push_back(assign_reg);
4625 case_node->children.push_back(cond_node);
4626 }
4627
4628 std::vector<RTLIL::State> x_bits;
4629 for (int i = 0; i < mem_width; i++)
4630 x_bits.push_back(RTLIL::State::Sx);
4631
4632 AstNode *cond_node = new AstNode(AST_COND, new AstNode(AST_DEFAULT), new AstNode(AST_BLOCK));
4633 AstNode *assign_reg = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), AstNode::mkconst_bits(x_bits, false));
4634 assign_reg->children[0]->str = id_data;
4635 assign_reg->children[0]->was_checked = true;
4636 cond_node->children[1]->children.push_back(assign_reg);
4637 case_node->children.push_back(cond_node);
4638
4639 if (block)
4640 {
4641 size_t assign_idx = 0;
4642 while (assign_idx < block->children.size() && !block->children[assign_idx]->contains(this))
4643 assign_idx++;
4644 log_assert(assign_idx < block->children.size());
4645 block->children.insert(block->children.begin()+assign_idx, case_node);
4646 block->children.insert(block->children.begin()+assign_idx, assign_addr);
4647 }
4648 else
4649 {
4650 AstNode *proc = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
4651 proc->children[0]->children.push_back(case_node);
4652 mod->children.push_back(proc);
4653 mod->children.push_back(assign_addr);
4654 }
4655
4656 delete_children();
4657 range_valid = false;
4658 id2ast = NULL;
4659 str = id_data;
4660 }
4661
4662 if (bit_part_sel)
4663 children.push_back(bit_part_sel);
4664
4665 did_something = true;
4666 }
4667
4668 log_assert(id2ast == NULL || mem2reg_set.count(id2ast) == 0);
4669
4670 auto children_list = children;
4671 for (size_t i = 0; i < children_list.size(); i++)
4672 if (children_list[i]->mem2reg_as_needed_pass2(mem2reg_set, mod, block, async_block))
4673 did_something = true;
4674
4675 return did_something;
4676 }
4677
4678 // calculate memory dimensions
4679 void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits)
4680 {
4681 log_assert(type == AST_MEMORY);
4682
4683 mem_width = children[0]->range_left - children[0]->range_right + 1;
4684 mem_size = children[1]->range_left - children[1]->range_right;
4685
4686 if (mem_size < 0)
4687 mem_size *= -1;
4688 mem_size += min(children[1]->range_left, children[1]->range_right) + 1;
4689
4690 addr_bits = 1;
4691 while ((1 << addr_bits) < mem_size)
4692 addr_bits++;
4693 }
4694
4695 bool AstNode::detect_latch(const std::string &var)
4696 {
4697 switch (type)
4698 {
4699 case AST_ALWAYS:
4700 for (auto &c : children)
4701 {
4702 switch (c->type)
4703 {
4704 case AST_POSEDGE:
4705 case AST_NEGEDGE:
4706 return false;
4707 case AST_EDGE:
4708 break;
4709 case AST_BLOCK:
4710 if (!c->detect_latch(var))
4711 return false;
4712 break;
4713 default:
4714 log_abort();
4715 }
4716 }
4717 return true;
4718 case AST_BLOCK:
4719 for (auto &c : children)
4720 if (!c->detect_latch(var))
4721 return false;
4722 return true;
4723 case AST_CASE:
4724 {
4725 bool r = true;
4726 for (auto &c : children) {
4727 if (c->type == AST_COND) {
4728 if (c->children.at(1)->detect_latch(var))
4729 return true;
4730 r = false;
4731 }
4732 if (c->type == AST_DEFAULT) {
4733 if (c->children.at(0)->detect_latch(var))
4734 return true;
4735 r = false;
4736 }
4737 }
4738 return r;
4739 }
4740 case AST_ASSIGN_EQ:
4741 case AST_ASSIGN_LE:
4742 if (children.at(0)->type == AST_IDENTIFIER &&
4743 children.at(0)->children.empty() && children.at(0)->str == var)
4744 return false;
4745 return true;
4746 default:
4747 return true;
4748 }
4749 }
4750
4751 bool AstNode::has_const_only_constructs()
4752 {
4753 if (type == AST_WHILE || type == AST_REPEAT)
4754 return true;
4755 for (auto child : children)
4756 if (child->has_const_only_constructs())
4757 return true;
4758 return false;
4759 }
4760
4761 bool AstNode::is_simple_const_expr()
4762 {
4763 if (type == AST_IDENTIFIER)
4764 return false;
4765 for (auto child : children)
4766 if (!child->is_simple_const_expr())
4767 return false;
4768 return true;
4769 }
4770
4771 // helper function for AstNode::eval_const_function()
4772 bool AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &variables, AstNode *fcall, bool must_succeed)
4773 {
4774 if (type == AST_IDENTIFIER && variables.count(str)) {
4775 int offset = variables.at(str).offset, width = variables.at(str).val.bits.size();
4776 if (!children.empty()) {
4777 if (children.size() != 1 || children.at(0)->type != AST_RANGE) {
4778 if (!must_succeed)
4779 return false;
4780 log_file_error(filename, location.first_line, "Memory access in constant function is not supported\n%s: ...called from here.\n",
4781 fcall->loc_string().c_str());
4782 }
4783 if (!children.at(0)->replace_variables(variables, fcall, must_succeed))
4784 return false;
4785 while (simplify(true, false, false, 1, -1, false, true)) { }
4786 if (!children.at(0)->range_valid) {
4787 if (!must_succeed)
4788 return false;
4789 log_file_error(filename, location.first_line, "Non-constant range\n%s: ... called from here.\n",
4790 fcall->loc_string().c_str());
4791 }
4792 offset = min(children.at(0)->range_left, children.at(0)->range_right);
4793 width = min(std::abs(children.at(0)->range_left - children.at(0)->range_right) + 1, width);
4794 }
4795 offset -= variables.at(str).offset;
4796 std::vector<RTLIL::State> &var_bits = variables.at(str).val.bits;
4797 std::vector<RTLIL::State> new_bits(var_bits.begin() + offset, var_bits.begin() + offset + width);
4798 AstNode *newNode = mkconst_bits(new_bits, variables.at(str).is_signed);
4799 newNode->cloneInto(this);
4800 delete newNode;
4801 return true;
4802 }
4803
4804 for (auto &child : children)
4805 if (!child->replace_variables(variables, fcall, must_succeed))
4806 return false;
4807 return true;
4808 }
4809
4810 // attempt to statically evaluate a functions with all-const arguments
4811 AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed)
4812 {
4813 std::map<std::string, AstNode*> backup_scope = current_scope;
4814 std::map<std::string, AstNode::varinfo_t> variables;
4815 std::vector<AstNode*> to_delete;
4816 AstNode *block = new AstNode(AST_BLOCK);
4817 AstNode *result = nullptr;
4818
4819 size_t argidx = 0;
4820 for (auto child : children)
4821 {
4822 block->children.push_back(child->clone());
4823 }
4824
4825 while (!block->children.empty())
4826 {
4827 AstNode *stmt = block->children.front();
4828
4829 #if 0
4830 log("-----------------------------------\n");
4831 for (auto &it : variables)
4832 log("%20s %40s\n", it.first.c_str(), log_signal(it.second.val));
4833 stmt->dumpAst(NULL, "stmt> ");
4834 #endif
4835
4836 if (stmt->type == AST_WIRE)
4837 {
4838 while (stmt->simplify(true, false, false, 1, -1, false, true)) { }
4839 if (!stmt->range_valid) {
4840 if (!must_succeed)
4841 goto finished;
4842 log_file_error(stmt->filename, stmt->location.first_line, "Can't determine size of variable %s\n%s: ... called from here.\n",
4843 stmt->str.c_str(), fcall->loc_string().c_str());
4844 }
4845 AstNode::varinfo_t &variable = variables[stmt->str];
4846 int width = abs(stmt->range_left - stmt->range_right) + 1;
4847 // if this variable has already been declared as an input, check the
4848 // sizes match if it already had an explicit size
4849 if (variable.arg && variable.explicitly_sized && variable.val.size() != width) {
4850 log_file_error(filename, location.first_line, "Incompatible re-declaration of constant function wire %s.\n", stmt->str.c_str());
4851 }
4852 variable.val = RTLIL::Const(RTLIL::State::Sx, width);
4853 variable.offset = min(stmt->range_left, stmt->range_right);
4854 variable.is_signed = stmt->is_signed;
4855 variable.explicitly_sized = stmt->children.size() &&
4856 stmt->children.back()->type == AST_RANGE;
4857 // identify the argument corresponding to this wire, if applicable
4858 if (stmt->is_input && argidx < fcall->children.size()) {
4859 variable.arg = fcall->children.at(argidx++);
4860 }
4861 // load the constant arg's value into this variable
4862 if (variable.arg) {
4863 if (variable.arg->type == AST_CONSTANT) {
4864 variable.val = variable.arg->bitsAsConst(width);
4865 } else {
4866 log_assert(variable.arg->type == AST_REALVALUE);
4867 variable.val = variable.arg->realAsConst(width);
4868 }
4869 }
4870 current_scope[stmt->str] = stmt;
4871
4872 block->children.erase(block->children.begin());
4873 to_delete.push_back(stmt);
4874 continue;
4875 }
4876
4877 log_assert(variables.count(str) != 0);
4878
4879 if (stmt->type == AST_LOCALPARAM)
4880 {
4881 while (stmt->simplify(true, false, false, 1, -1, false, true)) { }
4882
4883 current_scope[stmt->str] = stmt;
4884
4885 block->children.erase(block->children.begin());
4886 to_delete.push_back(stmt);
4887 continue;
4888 }
4889
4890 if (stmt->type == AST_ASSIGN_EQ)
4891 {
4892 if (stmt->children.at(0)->type == AST_IDENTIFIER && stmt->children.at(0)->children.size() != 0 &&
4893 stmt->children.at(0)->children.at(0)->type == AST_RANGE)
4894 if (!stmt->children.at(0)->children.at(0)->replace_variables(variables, fcall, must_succeed))
4895 goto finished;
4896 if (!stmt->children.at(1)->replace_variables(variables, fcall, must_succeed))
4897 goto finished;
4898 while (stmt->simplify(true, false, false, 1, -1, false, true)) { }
4899
4900 if (stmt->type != AST_ASSIGN_EQ)
4901 continue;
4902
4903 if (stmt->children.at(1)->type != AST_CONSTANT) {
4904 if (!must_succeed)
4905 goto finished;
4906 log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here. X\n",
4907 fcall->loc_string().c_str());
4908 }
4909
4910 if (stmt->children.at(0)->type != AST_IDENTIFIER) {
4911 if (!must_succeed)
4912 goto finished;
4913 log_file_error(stmt->filename, stmt->location.first_line, "Unsupported composite left hand side in constant function\n%s: ... called from here.\n",
4914 fcall->loc_string().c_str());
4915 }
4916
4917 if (!variables.count(stmt->children.at(0)->str)) {
4918 if (!must_succeed)
4919 goto finished;
4920 log_file_error(stmt->filename, stmt->location.first_line, "Assignment to non-local variable in constant function\n%s: ... called from here.\n",
4921 fcall->loc_string().c_str());
4922 }
4923
4924 if (stmt->children.at(0)->children.empty()) {
4925 variables[stmt->children.at(0)->str].val = stmt->children.at(1)->bitsAsConst(variables[stmt->children.at(0)->str].val.bits.size());
4926 } else {
4927 AstNode *range = stmt->children.at(0)->children.at(0);
4928 if (!range->range_valid) {
4929 if (!must_succeed)
4930 goto finished;
4931 log_file_error(range->filename, range->location.first_line, "Non-constant range\n%s: ... called from here.\n",
4932 fcall->loc_string().c_str());
4933 }
4934 int offset = min(range->range_left, range->range_right);
4935 int width = std::abs(range->range_left - range->range_right) + 1;
4936 varinfo_t &v = variables[stmt->children.at(0)->str];
4937 RTLIL::Const r = stmt->children.at(1)->bitsAsConst(v.val.bits.size());
4938 for (int i = 0; i < width; i++)
4939 v.val.bits.at(i+offset-v.offset) = r.bits.at(i);
4940 }
4941
4942 delete block->children.front();
4943 block->children.erase(block->children.begin());
4944 continue;
4945 }
4946
4947 if (stmt->type == AST_FOR)
4948 {
4949 block->children.insert(block->children.begin(), stmt->children.at(0));
4950 stmt->children.at(3)->children.push_back(stmt->children.at(2));
4951 stmt->children.erase(stmt->children.begin() + 2);
4952 stmt->children.erase(stmt->children.begin());
4953 stmt->type = AST_WHILE;
4954 continue;
4955 }
4956
4957 if (stmt->type == AST_WHILE)
4958 {
4959 AstNode *cond = stmt->children.at(0)->clone();
4960 if (!cond->replace_variables(variables, fcall, must_succeed))
4961 goto finished;
4962 while (cond->simplify(true, false, false, 1, -1, false, true)) { }
4963
4964 if (cond->type != AST_CONSTANT) {
4965 if (!must_succeed)
4966 goto finished;
4967 log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n",
4968 fcall->loc_string().c_str());
4969 }
4970
4971 if (cond->asBool()) {
4972 block->children.insert(block->children.begin(), stmt->children.at(1)->clone());
4973 } else {
4974 delete block->children.front();
4975 block->children.erase(block->children.begin());
4976 }
4977
4978 delete cond;
4979 continue;
4980 }
4981
4982 if (stmt->type == AST_REPEAT)
4983 {
4984 AstNode *num = stmt->children.at(0)->clone();
4985 if (!num->replace_variables(variables, fcall, must_succeed))
4986 goto finished;
4987 while (num->simplify(true, false, false, 1, -1, false, true)) { }
4988
4989 if (num->type != AST_CONSTANT) {
4990 if (!must_succeed)
4991 goto finished;
4992 log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n",
4993 fcall->loc_string().c_str());
4994 }
4995
4996 block->children.erase(block->children.begin());
4997 for (int i = 0; i < num->bitsAsConst().as_int(); i++)
4998 block->children.insert(block->children.begin(), stmt->children.at(1)->clone());
4999
5000 delete stmt;
5001 delete num;
5002 continue;
5003 }
5004
5005 if (stmt->type == AST_CASE)
5006 {
5007 AstNode *expr = stmt->children.at(0)->clone();
5008 if (!expr->replace_variables(variables, fcall, must_succeed))
5009 goto finished;
5010 while (expr->simplify(true, false, false, 1, -1, false, true)) { }
5011
5012 AstNode *sel_case = NULL;
5013 for (size_t i = 1; i < stmt->children.size(); i++)
5014 {
5015 bool found_match = false;
5016 log_assert(stmt->children.at(i)->type == AST_COND || stmt->children.at(i)->type == AST_CONDX || stmt->children.at(i)->type == AST_CONDZ);
5017
5018 if (stmt->children.at(i)->children.front()->type == AST_DEFAULT) {
5019 sel_case = stmt->children.at(i)->children.back();
5020 continue;
5021 }
5022
5023 for (size_t j = 0; j+1 < stmt->children.at(i)->children.size() && !found_match; j++)
5024 {
5025 AstNode *cond = stmt->children.at(i)->children.at(j)->clone();
5026 if (!cond->replace_variables(variables, fcall, must_succeed))
5027 goto finished;
5028
5029 cond = new AstNode(AST_EQ, expr->clone(), cond);
5030 while (cond->simplify(true, false, false, 1, -1, false, true)) { }
5031
5032 if (cond->type != AST_CONSTANT) {
5033 if (!must_succeed)
5034 goto finished;
5035 log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n",
5036 fcall->loc_string().c_str());
5037 }
5038
5039 found_match = cond->asBool();
5040 delete cond;
5041 }
5042
5043 if (found_match) {
5044 sel_case = stmt->children.at(i)->children.back();
5045 break;
5046 }
5047 }
5048
5049 block->children.erase(block->children.begin());
5050 if (sel_case)
5051 block->children.insert(block->children.begin(), sel_case->clone());
5052 delete stmt;
5053 delete expr;
5054 continue;
5055 }
5056
5057 if (stmt->type == AST_BLOCK)
5058 {
5059 if (!stmt->str.empty())
5060 stmt->expand_genblock(stmt->str + ".");
5061
5062 block->children.erase(block->children.begin());
5063 block->children.insert(block->children.begin(), stmt->children.begin(), stmt->children.end());
5064 stmt->children.clear();
5065 delete stmt;
5066 continue;
5067 }
5068
5069 if (!must_succeed)
5070 goto finished;
5071 log_file_error(stmt->filename, stmt->location.first_line, "Unsupported language construct in constant function\n%s: ... called from here.\n",
5072 fcall->loc_string().c_str());
5073 log_abort();
5074 }
5075
5076 result = AstNode::mkconst_bits(variables.at(str).val.bits, variables.at(str).is_signed);
5077
5078 finished:
5079 delete block;
5080 current_scope = backup_scope;
5081
5082 for (auto it : to_delete) {
5083 delete it;
5084 }
5085 to_delete.clear();
5086
5087 return result;
5088 }
5089
5090 void AstNode::allocateDefaultEnumValues()
5091 {
5092 log_assert(type==AST_ENUM);
5093 log_assert(children.size() > 0);
5094 if (children.front()->attributes.count(ID::enum_base_type))
5095 return; // already elaborated
5096 int last_enum_int = -1;
5097 for (auto node : children) {
5098 log_assert(node->type==AST_ENUM_ITEM);
5099 node->attributes[ID::enum_base_type] = mkconst_str(str);
5100 for (size_t i = 0; i < node->children.size(); i++) {
5101 switch (node->children[i]->type) {
5102 case AST_NONE:
5103 // replace with auto-incremented constant
5104 delete node->children[i];
5105 node->children[i] = AstNode::mkconst_int(++last_enum_int, true);
5106 break;
5107 case AST_CONSTANT:
5108 // explicit constant (or folded expression)
5109 // TODO: can't extend 'x or 'z item
5110 last_enum_int = node->children[i]->integer;
5111 break;
5112 default:
5113 // ignore ranges
5114 break;
5115 }
5116 // TODO: range check
5117 }
5118 }
5119 }
5120
5121 bool AstNode::is_recursive_function() const
5122 {
5123 std::set<const AstNode *> visited;
5124 std::function<bool(const AstNode *node)> visit = [&](const AstNode *node) {
5125 if (visited.count(node))
5126 return node == this;
5127 visited.insert(node);
5128 if (node->type == AST_FCALL) {
5129 auto it = current_scope.find(node->str);
5130 if (it != current_scope.end() && visit(it->second))
5131 return true;
5132 }
5133 for (const AstNode *child : node->children) {
5134 if (visit(child))
5135 return true;
5136 }
5137 return false;
5138 };
5139
5140 log_assert(type == AST_FUNCTION);
5141 return visit(this);
5142 }
5143
5144 std::pair<AstNode*, AstNode*> AstNode::get_tern_choice()
5145 {
5146 if (!children[0]->isConst())
5147 return {};
5148
5149 bool found_sure_true = false;
5150 bool found_maybe_true = false;
5151
5152 if (children[0]->type == AST_CONSTANT)
5153 for (auto &bit : children[0]->bits) {
5154 if (bit == RTLIL::State::S1)
5155 found_sure_true = true;
5156 if (bit > RTLIL::State::S1)
5157 found_maybe_true = true;
5158 }
5159 else
5160 found_sure_true = children[0]->asReal(true) != 0;
5161
5162 AstNode *choice = nullptr, *not_choice = nullptr;
5163 if (found_sure_true)
5164 choice = children[1], not_choice = children[2];
5165 else if (!found_maybe_true)
5166 choice = children[2], not_choice = children[1];
5167
5168 return {choice, not_choice};
5169 }
5170
5171 std::string AstNode::try_pop_module_prefix() const
5172 {
5173 AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod;
5174 size_t pos = str.find('.', 1);
5175 if (str[0] == '\\' && pos != std::string::npos) {
5176 std::string new_str = "\\" + str.substr(pos + 1);
5177 if (current_scope.count(new_str)) {
5178 std::string prefix = str.substr(0, pos);
5179 auto it = current_scope_ast->attributes.find(ID::hdlname);
5180 if ((it != current_scope_ast->attributes.end() && it->second->str == prefix)
5181 || prefix == current_scope_ast->str)
5182 return new_str;
5183 }
5184 }
5185 return str;
5186 }
5187
5188 YOSYS_NAMESPACE_END