2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
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.
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.
20 * This is the AST frontend library.
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.
29 #include "kernel/log.h"
30 #include "libs/sha1/sha1.h"
40 using namespace AST_INTERNAL
;
42 // convert the AST into a simpler AST that has all parameters subsitited by their
43 // values, unrolled for-loops, expanded generate blocks, etc. when this function
44 // is done with an AST it can be converted into RTLIL using genRTLIL().
46 // this function also does all name resolving and sets the id2ast member of all
47 // nodes that link to a different node using names and lexical scoping.
48 bool AstNode::simplify(bool const_fold
, bool at_zero
, bool in_lvalue
, int stage
, int width_hint
, bool sign_hint
, bool in_param
)
50 AstNode
*newNode
= NULL
;
51 bool did_something
= false;
54 log("-------------\n");
55 log("const_fold=%d, at_zero=%d, in_lvalue=%d, stage=%d, width_hint=%d, sign_hint=%d, in_param=%d\n",
56 int(const_fold
), int(at_zero
), int(in_lvalue
), int(stage
), int(width_hint
), int(sign_hint
), int(in_param
));
62 log_assert(type
== AST_MODULE
);
64 while (simplify(const_fold
, at_zero
, in_lvalue
, 1, width_hint
, sign_hint
, in_param
)) { }
66 if (!flag_nomem2reg
&& !get_bool_attribute("\\nomem2reg"))
68 std::map
<AstNode
*, std::set
<std::string
>> mem2reg_places
;
69 std::map
<AstNode
*, uint32_t> mem2reg_candidates
, dummy_proc_flags
;
70 uint32_t flags
= flag_mem2reg
? AstNode::MEM2REG_FL_ALL
: 0;
71 mem2reg_as_needed_pass1(mem2reg_places
, mem2reg_candidates
, dummy_proc_flags
, flags
);
73 std::set
<AstNode
*> mem2reg_set
;
74 for (auto &it
: mem2reg_candidates
)
76 AstNode
*mem
= it
.first
;
77 uint32_t memflags
= it
.second
;
78 log_assert((memflags
& ~0x00ffff00) == 0);
80 if (mem
->get_bool_attribute("\\nomem2reg"))
83 if (memflags
& AstNode::MEM2REG_FL_FORCED
)
86 if (memflags
& AstNode::MEM2REG_FL_EQ2
)
87 goto verbose_activate
;
89 if (memflags
& AstNode::MEM2REG_FL_SET_ASYNC
)
90 goto verbose_activate
;
92 if ((memflags
& AstNode::MEM2REG_FL_SET_INIT
) && (memflags
& AstNode::MEM2REG_FL_SET_ELSE
))
93 goto verbose_activate
;
95 if (memflags
& AstNode::MEM2REG_FL_CMPLX_LHS
)
96 goto verbose_activate
;
98 // log("Note: Not replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
102 if (mem2reg_set
.count(mem
) == 0) {
103 log("Warning: Replacing memory %s with list of registers.", mem
->str
.c_str());
104 bool first_element
= true;
105 for (auto &place
: mem2reg_places
[it
.first
]) {
106 log("%s%s", first_element
? " See " : ", ", place
.c_str());
107 first_element
= false;
113 // log("Note: Replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
114 mem2reg_set
.insert(mem
);
117 for (auto node
: mem2reg_set
)
119 int mem_width
, mem_size
, addr_bits
;
120 node
->meminfo(mem_width
, mem_size
, addr_bits
);
122 for (int i
= 0; i
< mem_size
; i
++) {
123 AstNode
*reg
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
,
124 mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
125 reg
->str
= stringf("%s[%d]", node
->str
.c_str(), i
);
127 reg
->is_signed
= node
->is_signed
;
128 children
.push_back(reg
);
129 while (reg
->simplify(true, false, false, 1, -1, false, false)) { }
133 mem2reg_as_needed_pass2(mem2reg_set
, this, NULL
);
135 for (size_t i
= 0; i
< children
.size(); i
++) {
136 if (mem2reg_set
.count(children
[i
]) > 0) {
138 children
.erase(children
.begin() + (i
--));
143 while (simplify(const_fold
, at_zero
, in_lvalue
, 2, width_hint
, sign_hint
, in_param
)) { }
147 current_filename
= filename
;
148 set_line_num(linenum
);
150 // we do not look inside a task or function
151 // (but as soon as a task of function is instanciated we process the generated AST as usual)
152 if (type
== AST_FUNCTION
|| type
== AST_TASK
)
155 // deactivate all calls to non-synthesis system taks
156 if ((type
== AST_FCALL
|| type
== AST_TCALL
) && (str
== "$display" || str
== "$stop" || str
== "$finish")) {
161 // activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
162 if (type
== AST_WIRE
|| type
== AST_PARAMETER
|| type
== AST_LOCALPARAM
|| type
== AST_DEFPARAM
|| type
== AST_PARASET
|| type
== AST_RANGE
|| type
== AST_PREFIX
)
164 if (type
== AST_IDENTIFIER
&& current_scope
.count(str
) > 0 && (current_scope
[str
]->type
== AST_PARAMETER
|| current_scope
[str
]->type
== AST_LOCALPARAM
))
167 // in certain cases a function must be evaluated constant. this is what in_param controls.
168 if (type
== AST_PARAMETER
|| type
== AST_LOCALPARAM
|| type
== AST_DEFPARAM
|| type
== AST_PARASET
|| type
== AST_PREFIX
)
171 std::map
<std::string
, AstNode
*> backup_scope
;
173 // create name resolution entries for all objects with names
174 // also merge multiple declarations for the same wire (e.g. "output foobar; reg foobar;")
175 if (type
== AST_MODULE
) {
176 current_scope
.clear();
177 std::map
<std::string
, AstNode
*> this_wire_scope
;
178 for (size_t i
= 0; i
< children
.size(); i
++) {
179 AstNode
*node
= children
[i
];
180 if (node
->type
== AST_WIRE
) {
181 if (this_wire_scope
.count(node
->str
) > 0) {
182 AstNode
*first_node
= this_wire_scope
[node
->str
];
183 if (!node
->is_input
&& !node
->is_output
&& node
->is_reg
&& node
->children
.size() == 0)
184 goto wires_are_compatible
;
185 if (first_node
->children
.size() != node
->children
.size())
186 goto wires_are_incompatible
;
187 for (size_t j
= 0; j
< node
->children
.size(); j
++) {
188 AstNode
*n1
= first_node
->children
[j
], *n2
= node
->children
[j
];
189 if (n1
->type
== AST_RANGE
&& n2
->type
== AST_RANGE
&& n1
->range_valid
&& n2
->range_valid
) {
190 if (n1
->range_left
!= n2
->range_left
)
191 goto wires_are_incompatible
;
192 if (n1
->range_right
!= n2
->range_right
)
193 goto wires_are_incompatible
;
194 } else if (*n1
!= *n2
)
195 goto wires_are_incompatible
;
197 if (first_node
->range_left
!= node
->range_left
)
198 goto wires_are_incompatible
;
199 if (first_node
->range_right
!= node
->range_right
)
200 goto wires_are_incompatible
;
201 if (first_node
->port_id
== 0 && (node
->is_input
|| node
->is_output
))
202 goto wires_are_incompatible
;
203 wires_are_compatible
:
205 first_node
->is_input
= true;
207 first_node
->is_output
= true;
209 first_node
->is_reg
= true;
211 first_node
->is_signed
= true;
212 for (auto &it
: node
->attributes
) {
213 if (first_node
->attributes
.count(it
.first
) > 0)
214 delete first_node
->attributes
[it
.first
];
215 first_node
->attributes
[it
.first
] = it
.second
->clone();
217 children
.erase(children
.begin()+(i
--));
218 did_something
= true;
221 wires_are_incompatible
:
223 log_error("Incompatible re-declaration of wire %s at %s:%d.\n", node
->str
.c_str(), filename
.c_str(), linenum
);
226 this_wire_scope
[node
->str
] = node
;
228 if (node
->type
== AST_PARAMETER
|| node
->type
== AST_LOCALPARAM
|| node
->type
== AST_WIRE
|| node
->type
== AST_AUTOWIRE
|| node
->type
== AST_GENVAR
||
229 node
->type
== AST_MEMORY
|| node
->type
== AST_FUNCTION
|| node
->type
== AST_TASK
|| node
->type
== AST_CELL
) {
230 backup_scope
[node
->str
] = current_scope
[node
->str
];
231 current_scope
[node
->str
] = node
;
234 for (size_t i
= 0; i
< children
.size(); i
++) {
235 AstNode
*node
= children
[i
];
236 if (node
->type
== AST_PARAMETER
|| node
->type
== AST_LOCALPARAM
|| node
->type
== AST_WIRE
|| node
->type
== AST_AUTOWIRE
)
237 while (node
->simplify(true, false, false, 1, -1, false, node
->type
== AST_PARAMETER
|| node
->type
== AST_LOCALPARAM
))
238 did_something
= true;
242 auto backup_current_block
= current_block
;
243 auto backup_current_block_child
= current_block_child
;
244 auto backup_current_top_block
= current_top_block
;
246 int backup_width_hint
= width_hint
;
247 bool backup_sign_hint
= sign_hint
;
249 bool detect_width_simple
= false;
250 bool child_0_is_self_determined
= false;
251 bool child_1_is_self_determined
= false;
252 bool child_2_is_self_determined
= false;
253 bool children_are_self_determined
= false;
254 bool reset_width_after_children
= false;
261 while (!children
[0]->basic_prep
&& children
[0]->simplify(false, false, true, stage
, -1, false, in_param
) == true)
262 did_something
= true;
263 while (!children
[1]->basic_prep
&& children
[1]->simplify(false, false, false, stage
, -1, false, in_param
) == true)
264 did_something
= true;
265 children
[0]->detectSignWidth(backup_width_hint
, backup_sign_hint
);
266 children
[1]->detectSignWidth(width_hint
, sign_hint
);
267 width_hint
= std::max(width_hint
, backup_width_hint
);
268 child_0_is_self_determined
= true;
273 while (!children
[0]->basic_prep
&& children
[0]->simplify(false, false, false, stage
, -1, false, true) == true)
274 did_something
= true;
275 children
[0]->detectSignWidth(width_hint
, sign_hint
);
276 if (children
.size() > 1 && children
[1]->type
== AST_RANGE
) {
277 while (!children
[1]->basic_prep
&& children
[1]->simplify(false, false, false, stage
, -1, false, true) == true)
278 did_something
= true;
279 if (!children
[1]->range_valid
)
280 log_error("Non-constant width range on parameter decl at %s:%d.\n", filename
.c_str(), linenum
);
281 width_hint
= std::max(width_hint
, children
[1]->range_left
- children
[1]->range_right
+ 1);
287 case AST_TO_UNSIGNED
:
293 case AST_REDUCE_XNOR
:
294 case AST_REDUCE_BOOL
:
295 detect_width_simple
= true;
296 children_are_self_determined
= true;
311 detect_width_simple
= true;
315 case AST_SHIFT_RIGHT
:
316 case AST_SHIFT_SLEFT
:
317 case AST_SHIFT_SRIGHT
:
319 detect_width_simple
= true;
320 child_1_is_self_determined
= true;
333 for (auto child
: children
) {
334 while (!child
->basic_prep
&& child
->simplify(false, false, in_lvalue
, stage
, -1, false, in_param
) == true)
335 did_something
= true;
336 child
->detectSignWidthWorker(width_hint
, sign_hint
);
338 reset_width_after_children
= true;
344 detect_width_simple
= true;
345 children_are_self_determined
= true;
349 detect_width_simple
= true;
350 child_0_is_self_determined
= true;
354 detect_width_simple
= true;
355 children_are_self_determined
= true;
363 if (detect_width_simple
&& width_hint
< 0) {
364 if (type
== AST_REPLICATE
)
365 while (children
[0]->simplify(true, false, in_lvalue
, stage
, -1, false, true) == true)
366 did_something
= true;
367 for (auto child
: children
)
368 while (!child
->basic_prep
&& child
->simplify(false, false, in_lvalue
, stage
, -1, false, in_param
) == true)
369 did_something
= true;
370 detectSignWidth(width_hint
, sign_hint
);
373 if (type
== AST_TERNARY
) {
374 int width_hint_left
, width_hint_right
;
375 bool sign_hint_left
, sign_hint_right
;
376 bool found_real_left
, found_real_right
;
377 children
[1]->detectSignWidth(width_hint_left
, sign_hint_left
, &found_real_left
);
378 children
[2]->detectSignWidth(width_hint_right
, sign_hint_right
, &found_real_right
);
379 if (found_real_left
|| found_real_right
) {
380 child_1_is_self_determined
= true;
381 child_2_is_self_determined
= true;
385 // simplify all children first
386 // (iterate by index as e.g. auto wires can add new children in the process)
387 for (size_t i
= 0; i
< children
.size(); i
++) {
388 bool did_something_here
= true;
389 if ((type
== AST_GENFOR
|| type
== AST_FOR
) && i
>= 3)
391 if ((type
== AST_GENIF
|| type
== AST_GENCASE
) && i
>= 1)
393 if (type
== AST_GENBLOCK
)
395 if (type
== AST_BLOCK
&& !str
.empty())
397 if (type
== AST_PREFIX
&& i
>= 1)
399 while (did_something_here
&& i
< children
.size()) {
400 bool const_fold_here
= const_fold
, in_lvalue_here
= in_lvalue
;
401 int width_hint_here
= width_hint
;
402 bool sign_hint_here
= sign_hint
;
403 bool in_param_here
= in_param
;
404 if (i
== 0 && (type
== AST_REPLICATE
|| type
== AST_WIRE
))
405 const_fold_here
= true, in_param_here
= true;
406 if (type
== AST_PARAMETER
|| type
== AST_LOCALPARAM
)
407 const_fold_here
= true;
408 if (i
== 0 && (type
== AST_ASSIGN
|| type
== AST_ASSIGN_EQ
|| type
== AST_ASSIGN_LE
))
409 in_lvalue_here
= true;
410 if (type
== AST_BLOCK
) {
411 current_block
= this;
412 current_block_child
= children
[i
];
414 if ((type
== AST_ALWAYS
|| type
== AST_INITIAL
) && children
[i
]->type
== AST_BLOCK
)
415 current_top_block
= children
[i
];
416 if (i
== 0 && child_0_is_self_determined
)
417 width_hint_here
= -1, sign_hint_here
= false;
418 if (i
== 1 && child_1_is_self_determined
)
419 width_hint_here
= -1, sign_hint_here
= false;
420 if (i
== 2 && child_2_is_self_determined
)
421 width_hint_here
= -1, sign_hint_here
= false;
422 if (children_are_self_determined
)
423 width_hint_here
= -1, sign_hint_here
= false;
424 did_something_here
= children
[i
]->simplify(const_fold_here
, at_zero
, in_lvalue_here
, stage
, width_hint_here
, sign_hint_here
, in_param_here
);
425 if (did_something_here
)
426 did_something
= true;
428 if (stage
== 2 && children
[i
]->type
== AST_INITIAL
&& current_ast_mod
!= this) {
429 current_ast_mod
->children
.push_back(children
[i
]);
430 children
.erase(children
.begin() + (i
--));
431 did_something
= true;
434 for (auto &attr
: attributes
) {
435 while (attr
.second
->simplify(true, false, false, stage
, -1, false, true))
436 did_something
= true;
439 if (reset_width_after_children
) {
440 width_hint
= backup_width_hint
;
441 sign_hint
= backup_sign_hint
;
443 detectSignWidth(width_hint
, sign_hint
);
446 current_block
= backup_current_block
;
447 current_block_child
= backup_current_block_child
;
448 current_top_block
= backup_current_top_block
;
450 for (auto it
= backup_scope
.begin(); it
!= backup_scope
.end(); it
++) {
451 if (it
->second
== NULL
)
452 current_scope
.erase(it
->first
);
454 current_scope
[it
->first
] = it
->second
;
457 current_filename
= filename
;
458 set_line_num(linenum
);
460 if (type
== AST_MODULE
)
461 current_scope
.clear();
463 // convert defparam nodes to cell parameters
464 if (type
== AST_DEFPARAM
&& !str
.empty()) {
465 size_t pos
= str
.rfind('.');
466 if (pos
== std::string::npos
)
467 log_error("Defparam `%s' does not contain a dot (module/parameter seperator) at %s:%d!\n",
468 RTLIL::unescape_id(str
).c_str(), filename
.c_str(), linenum
);
469 std::string modname
= str
.substr(0, pos
), paraname
= "\\" + str
.substr(pos
+1);
470 if (current_scope
.count(modname
) == 0 || current_scope
.at(modname
)->type
!= AST_CELL
)
471 log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::unescape_id(modname
).c_str(), RTLIL::unescape_id(paraname
).c_str(), filename
.c_str(), linenum
);
472 AstNode
*cell
= current_scope
.at(modname
), *paraset
= clone();
473 cell
->children
.insert(cell
->children
.begin() + 1, paraset
);
474 paraset
->type
= AST_PARASET
;
475 paraset
->str
= paraname
;
479 // resolve constant prefixes
480 if (type
== AST_PREFIX
) {
481 if (children
[0]->type
!= AST_CONSTANT
) {
482 // dumpAst(NULL, "> ");
483 log_error("Index in generate block prefix syntax at %s:%d is not constant!\n", filename
.c_str(), linenum
);
485 log_assert(children
[1]->type
== AST_IDENTIFIER
);
486 newNode
= children
[1]->clone();
487 const char *second_part
= children
[1]->str
.c_str();
488 if (second_part
[0] == '\\')
490 newNode
->str
= stringf("%s[%d].%s", str
.c_str(), children
[0]->integer
, second_part
);
494 // evaluate TO_BITS nodes
495 if (type
== AST_TO_BITS
) {
496 if (children
[0]->type
!= AST_CONSTANT
)
497 log_error("Left operand of to_bits expression is not constant at %s:%d!\n", filename
.c_str(), linenum
);
498 if (children
[1]->type
!= AST_CONSTANT
)
499 log_error("Right operand of to_bits expression is not constant at %s:%d!\n", filename
.c_str(), linenum
);
500 RTLIL::Const new_value
= children
[1]->bitsAsConst(children
[0]->bitsAsConst().as_int(), children
[1]->is_signed
);
501 newNode
= mkconst_bits(new_value
.bits
, children
[1]->is_signed
);
505 // annotate constant ranges
506 if (type
== AST_RANGE
) {
507 bool old_range_valid
= range_valid
;
509 range_swapped
= false;
512 log_assert(children
.size() >= 1);
513 if (children
[0]->type
== AST_CONSTANT
) {
515 range_left
= children
[0]->integer
;
516 if (children
.size() == 1)
517 range_right
= range_left
;
519 if (children
.size() >= 2) {
520 if (children
[1]->type
== AST_CONSTANT
)
521 range_right
= children
[1]->integer
;
525 if (old_range_valid
!= range_valid
)
526 did_something
= true;
527 if (range_valid
&& range_left
>= 0 && range_right
> range_left
) {
528 int tmp
= range_right
;
529 range_right
= range_left
;
531 range_swapped
= true;
535 // annotate wires with their ranges
536 if (type
== AST_WIRE
) {
537 if (children
.size() > 0) {
538 if (children
[0]->range_valid
) {
540 did_something
= true;
542 range_swapped
= children
[0]->range_swapped
;
543 range_left
= children
[0]->range_left
;
544 range_right
= children
[0]->range_right
;
548 did_something
= true;
550 range_swapped
= false;
556 // resolve multiranges on memory decl
557 if (type
== AST_MEMORY
&& children
.size() > 1 && children
[1]->type
== AST_MULTIRANGE
)
560 multirange_dimensions
.clear();
561 for (auto range
: children
[1]->children
) {
562 if (!range
->range_valid
)
563 log_error("Non-constant range on memory decl at %s:%d.\n", filename
.c_str(), linenum
);
564 multirange_dimensions
.push_back(std::min(range
->range_left
, range
->range_right
));
565 multirange_dimensions
.push_back(std::max(range
->range_left
, range
->range_right
) - std::min(range
->range_left
, range
->range_right
) + 1);
566 total_size
*= multirange_dimensions
.back();
569 children
[1] = new AstNode(AST_RANGE
, AstNode::mkconst_int(0, true), AstNode::mkconst_int(total_size
-1, true));
570 did_something
= true;
573 // resolve multiranges on memory access
574 if (type
== AST_IDENTIFIER
&& id2ast
&& id2ast
->type
== AST_MEMORY
&& children
.size() > 0 && children
[0]->type
== AST_MULTIRANGE
)
576 AstNode
*index_expr
= nullptr;
578 for (int i
= 0; 2*i
< SIZE(id2ast
->multirange_dimensions
); i
++)
580 if (SIZE(children
[0]->children
) < i
)
581 log_error("Insufficient number of array indices for %s at %s:%d.\n", log_id(str
), filename
.c_str(), linenum
);
583 AstNode
*new_index_expr
= children
[0]->children
[i
]->children
.at(0)->clone();
585 if (id2ast
->multirange_dimensions
[2*i
])
586 new_index_expr
= new AstNode(AST_SUB
, new_index_expr
, AstNode::mkconst_int(id2ast
->multirange_dimensions
[2*i
], true));
589 index_expr
= new_index_expr
;
591 index_expr
= new AstNode(AST_ADD
, new AstNode(AST_MUL
, index_expr
, AstNode::mkconst_int(id2ast
->multirange_dimensions
[2*i
-1], true)), new_index_expr
);
594 for (int i
= SIZE(id2ast
->multirange_dimensions
)/1; i
< SIZE(children
[0]->children
); i
++)
595 children
.push_back(children
[0]->children
[i
]->clone());
598 if (index_expr
== nullptr)
599 children
.erase(children
.begin());
601 children
[0] = new AstNode(AST_RANGE
, index_expr
);
603 did_something
= true;
606 // trim/extend parameters
607 if (type
== AST_PARAMETER
|| type
== AST_LOCALPARAM
) {
608 if (children
.size() > 1 && children
[1]->type
== AST_RANGE
) {
609 if (!children
[1]->range_valid
)
610 log_error("Non-constant width range on parameter decl at %s:%d.\n", filename
.c_str(), linenum
);
611 int width
= children
[1]->range_left
- children
[1]->range_right
+ 1;
612 if (children
[0]->type
== AST_REALVALUE
) {
613 RTLIL::Const constvalue
= children
[0]->realAsConst(width
);
614 log("Warning: converting real value %e to binary %s at %s:%d.\n",
615 children
[0]->realvalue
, log_signal(constvalue
), filename
.c_str(), linenum
);
617 children
[0] = mkconst_bits(constvalue
.bits
, sign_hint
);
618 did_something
= true;
620 if (children
[0]->type
== AST_CONSTANT
) {
621 if (width
!= int(children
[0]->bits
.size())) {
622 RTLIL::SigSpec
sig(children
[0]->bits
);
623 sig
.extend_u0(width
, children
[0]->is_signed
);
624 AstNode
*old_child_0
= children
[0];
625 children
[0] = mkconst_bits(sig
.as_const().bits
, children
[0]->is_signed
);
628 children
[0]->is_signed
= is_signed
;
631 range_swapped
= children
[1]->range_swapped
;
632 range_left
= children
[1]->range_left
;
633 range_right
= children
[1]->range_right
;
635 if (children
.size() > 1 && children
[1]->type
== AST_REALVALUE
&& children
[0]->type
== AST_CONSTANT
) {
636 double as_realvalue
= children
[0]->asReal(sign_hint
);
638 children
[0] = new AstNode(AST_REALVALUE
);
639 children
[0]->realvalue
= as_realvalue
;
640 did_something
= true;
644 // annotate identifiers using scope resolution and create auto-wires as needed
645 if (type
== AST_IDENTIFIER
) {
646 if (current_scope
.count(str
) == 0) {
647 for (auto node
: current_ast_mod
->children
) {
648 if ((node
->type
== AST_PARAMETER
|| node
->type
== AST_LOCALPARAM
|| node
->type
== AST_WIRE
|| node
->type
== AST_AUTOWIRE
|| node
->type
== AST_GENVAR
||
649 node
->type
== AST_MEMORY
|| node
->type
== AST_FUNCTION
|| node
->type
== AST_TASK
) && str
== node
->str
) {
650 current_scope
[node
->str
] = node
;
655 if (current_scope
.count(str
) == 0) {
656 // log("Warning: Creating auto-wire `%s' in module `%s'.\n", str.c_str(), current_ast_mod->str.c_str());
657 AstNode
*auto_wire
= new AstNode(AST_AUTOWIRE
);
658 auto_wire
->str
= str
;
659 current_ast_mod
->children
.push_back(auto_wire
);
660 current_scope
[str
] = auto_wire
;
661 did_something
= true;
663 if (id2ast
!= current_scope
[str
]) {
664 id2ast
= current_scope
[str
];
665 did_something
= true;
669 // split memory access with bit select to individual statements
670 if (type
== AST_IDENTIFIER
&& children
.size() == 2 && children
[0]->type
== AST_RANGE
&& children
[1]->type
== AST_RANGE
&& !in_lvalue
)
672 if (id2ast
== NULL
|| id2ast
->type
!= AST_MEMORY
|| children
[0]->children
.size() != 1)
673 log_error("Invalid bit-select on memory access at %s:%d!\n", filename
.c_str(), linenum
);
675 int mem_width
, mem_size
, addr_bits
;
676 id2ast
->meminfo(mem_width
, mem_size
, addr_bits
);
678 std::stringstream sstr
;
679 sstr
<< "$mem2bits$" << children
[0]->str
<< "$" << filename
<< ":" << linenum
<< "$" << (autoidx
++);
680 std::string wire_id
= sstr
.str();
682 AstNode
*wire
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
685 wire
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
686 current_ast_mod
->children
.push_back(wire
);
687 while (wire
->simplify(true, false, false, 1, -1, false, false)) { }
689 AstNode
*data
= clone();
690 delete data
->children
[1];
691 data
->children
.pop_back();
693 AstNode
*assign
= new AstNode(AST_ASSIGN_EQ
, new AstNode(AST_IDENTIFIER
), data
);
694 assign
->children
[0]->str
= wire_id
;
698 size_t assign_idx
= 0;
699 while (assign_idx
< current_block
->children
.size() && current_block
->children
[assign_idx
] != current_block_child
)
701 log_assert(assign_idx
< current_block
->children
.size());
702 current_block
->children
.insert(current_block
->children
.begin()+assign_idx
, assign
);
707 AstNode
*proc
= new AstNode(AST_ALWAYS
, new AstNode(AST_BLOCK
));
708 proc
->children
[0]->children
.push_back(assign
);
709 current_ast_mod
->children
.push_back(proc
);
712 newNode
= new AstNode(AST_IDENTIFIER
, children
[1]->clone());
713 newNode
->str
= wire_id
;
714 newNode
->id2ast
= wire
;
718 if (type
== AST_WHILE
)
719 log_error("While loops are only allowed in constant functions at %s:%d!\n", filename
.c_str(), linenum
);
721 if (type
== AST_REPEAT
)
722 log_error("Repeat loops are only allowed in constant functions at %s:%d!\n", filename
.c_str(), linenum
);
724 // unroll for loops and generate-for blocks
725 if ((type
== AST_GENFOR
|| type
== AST_FOR
) && children
.size() != 0)
727 AstNode
*init_ast
= children
[0];
728 AstNode
*while_ast
= children
[1];
729 AstNode
*next_ast
= children
[2];
730 AstNode
*body_ast
= children
[3];
732 while (body_ast
->type
== AST_GENBLOCK
&& body_ast
->str
.empty() &&
733 body_ast
->children
.size() == 1 && body_ast
->children
.at(0)->type
== AST_GENBLOCK
)
734 body_ast
= body_ast
->children
.at(0);
736 if (init_ast
->type
!= AST_ASSIGN_EQ
)
737 log_error("Unsupported 1st expression of generate for-loop at %s:%d!\n", filename
.c_str(), linenum
);
738 if (next_ast
->type
!= AST_ASSIGN_EQ
)
739 log_error("Unsupported 3rd expression of generate for-loop at %s:%d!\n", filename
.c_str(), linenum
);
741 if (type
== AST_GENFOR
) {
742 if (init_ast
->children
[0]->id2ast
== NULL
|| init_ast
->children
[0]->id2ast
->type
!= AST_GENVAR
)
743 log_error("Left hand side of 1st expression of generate for-loop at %s:%d is not a gen var!\n", filename
.c_str(), linenum
);
744 if (next_ast
->children
[0]->id2ast
== NULL
|| next_ast
->children
[0]->id2ast
->type
!= AST_GENVAR
)
745 log_error("Left hand side of 3rd expression of generate for-loop at %s:%d is not a gen var!\n", filename
.c_str(), linenum
);
747 if (init_ast
->children
[0]->id2ast
== NULL
|| init_ast
->children
[0]->id2ast
->type
!= AST_WIRE
)
748 log_error("Left hand side of 1st expression of generate for-loop at %s:%d is not a register!\n", filename
.c_str(), linenum
);
749 if (next_ast
->children
[0]->id2ast
== NULL
|| next_ast
->children
[0]->id2ast
->type
!= AST_WIRE
)
750 log_error("Left hand side of 3rd expression of generate for-loop at %s:%d is not a register!\n", filename
.c_str(), linenum
);
753 if (init_ast
->children
[0]->id2ast
!= next_ast
->children
[0]->id2ast
)
754 log_error("Incompatible left-hand sides in 1st and 3rd expression of generate for-loop at %s:%d!\n", filename
.c_str(), linenum
);
756 // eval 1st expression
757 AstNode
*varbuf
= init_ast
->children
[1]->clone();
758 while (varbuf
->simplify(true, false, false, stage
, width_hint
, sign_hint
, false)) { }
760 if (varbuf
->type
!= AST_CONSTANT
)
761 log_error("Right hand side of 1st expression of generate for-loop at %s:%d is not constant!\n", filename
.c_str(), linenum
);
763 varbuf
= new AstNode(AST_LOCALPARAM
, varbuf
);
764 varbuf
->str
= init_ast
->children
[0]->str
;
766 AstNode
*backup_scope_varbuf
= current_scope
[varbuf
->str
];
767 current_scope
[varbuf
->str
] = varbuf
;
769 size_t current_block_idx
= 0;
770 if (type
== AST_FOR
) {
771 while (current_block_idx
< current_block
->children
.size() &&
772 current_block
->children
[current_block_idx
] != current_block_child
)
778 // eval 2nd expression
779 AstNode
*buf
= while_ast
->clone();
780 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
, false)) { }
782 if (buf
->type
!= AST_CONSTANT
)
783 log_error("2nd expression of generate for-loop at %s:%d is not constant!\n", filename
.c_str(), linenum
);
785 if (buf
->integer
== 0) {
792 int index
= varbuf
->children
[0]->integer
;
793 if (body_ast
->type
== AST_GENBLOCK
)
794 buf
= body_ast
->clone();
796 buf
= new AstNode(AST_GENBLOCK
, body_ast
->clone());
797 if (buf
->str
.empty()) {
798 std::stringstream sstr
;
799 sstr
<< "$genblock$" << filename
<< ":" << linenum
<< "$" << (autoidx
++);
800 buf
->str
= sstr
.str();
802 std::map
<std::string
, std::string
> name_map
;
803 std::stringstream sstr
;
804 sstr
<< buf
->str
<< "[" << index
<< "].";
805 buf
->expand_genblock(varbuf
->str
, sstr
.str(), name_map
);
807 if (type
== AST_GENFOR
) {
808 for (size_t i
= 0; i
< buf
->children
.size(); i
++) {
809 buf
->children
[i
]->simplify(false, false, false, stage
, -1, false, false);
810 current_ast_mod
->children
.push_back(buf
->children
[i
]);
813 for (size_t i
= 0; i
< buf
->children
.size(); i
++)
814 current_block
->children
.insert(current_block
->children
.begin() + current_block_idx
++, buf
->children
[i
]);
816 buf
->children
.clear();
819 // eval 3rd expression
820 buf
= next_ast
->children
[1]->clone();
821 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
, false)) { }
823 if (buf
->type
!= AST_CONSTANT
)
824 log_error("Right hand side of 3rd expression of generate for-loop at %s:%d is not constant!\n", filename
.c_str(), linenum
);
826 delete varbuf
->children
[0];
827 varbuf
->children
[0] = buf
;
830 current_scope
[varbuf
->str
] = backup_scope_varbuf
;
833 did_something
= true;
836 // transform block with name
837 if (type
== AST_BLOCK
&& !str
.empty())
839 std::map
<std::string
, std::string
> name_map
;
840 expand_genblock(std::string(), str
+ ".", name_map
);
842 std::vector
<AstNode
*> new_children
;
843 for (size_t i
= 0; i
< children
.size(); i
++)
844 if (children
[i
]->type
== AST_WIRE
) {
845 children
[i
]->simplify(false, false, false, stage
, -1, false, false);
846 current_ast_mod
->children
.push_back(children
[i
]);
847 current_scope
[children
[i
]->str
] = children
[i
];
849 new_children
.push_back(children
[i
]);
851 children
.swap(new_children
);
852 did_something
= true;
856 // simplify unconditional generate block
857 if (type
== AST_GENBLOCK
&& children
.size() != 0)
860 std::map
<std::string
, std::string
> name_map
;
861 expand_genblock(std::string(), str
+ ".", name_map
);
864 for (size_t i
= 0; i
< children
.size(); i
++) {
865 children
[i
]->simplify(false, false, false, stage
, -1, false, false);
866 current_ast_mod
->children
.push_back(children
[i
]);
870 did_something
= true;
873 // simplify generate-if blocks
874 if (type
== AST_GENIF
&& children
.size() != 0)
876 AstNode
*buf
= children
[0]->clone();
877 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
, false)) { }
878 if (buf
->type
!= AST_CONSTANT
) {
879 // for (auto f : log_files)
880 // dumpAst(f, "verilog-ast> ");
881 log_error("Condition for generate if at %s:%d is not constant!\n", filename
.c_str(), linenum
);
883 if (buf
->asBool() != 0) {
885 buf
= children
[1]->clone();
888 buf
= children
.size() > 2 ? children
[2]->clone() : NULL
;
893 if (buf
->type
!= AST_GENBLOCK
)
894 buf
= new AstNode(AST_GENBLOCK
, buf
);
896 if (!buf
->str
.empty()) {
897 std::map
<std::string
, std::string
> name_map
;
898 buf
->expand_genblock(std::string(), buf
->str
+ ".", name_map
);
901 for (size_t i
= 0; i
< buf
->children
.size(); i
++) {
902 buf
->children
[i
]->simplify(false, false, false, stage
, -1, false, false);
903 current_ast_mod
->children
.push_back(buf
->children
[i
]);
906 buf
->children
.clear();
911 did_something
= true;
914 // simplify generate-case blocks
915 if (type
== AST_GENCASE
&& children
.size() != 0)
917 AstNode
*buf
= children
[0]->clone();
918 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
, false)) { }
919 if (buf
->type
!= AST_CONSTANT
) {
920 // for (auto f : log_files)
921 // dumpAst(f, "verilog-ast> ");
922 log_error("Condition for generate case at %s:%d is not constant!\n", filename
.c_str(), linenum
);
925 bool ref_signed
= buf
->is_signed
;
926 RTLIL::Const ref_value
= buf
->bitsAsConst();
929 AstNode
*selected_case
= NULL
;
930 for (size_t i
= 1; i
< children
.size(); i
++)
932 log_assert(children
.at(i
)->type
== AST_COND
);
934 AstNode
*this_genblock
= NULL
;
935 for (auto child
: children
.at(i
)->children
) {
936 log_assert(this_genblock
== NULL
);
937 if (child
->type
== AST_GENBLOCK
)
938 this_genblock
= child
;
941 for (auto child
: children
.at(i
)->children
)
943 if (child
->type
== AST_DEFAULT
) {
944 if (selected_case
== NULL
)
945 selected_case
= this_genblock
;
948 if (child
->type
== AST_GENBLOCK
)
951 buf
= child
->clone();
952 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
, false)) { }
953 if (buf
->type
!= AST_CONSTANT
) {
954 // for (auto f : log_files)
955 // dumpAst(f, "verilog-ast> ");
956 log_error("Expression in generate case at %s:%d is not constant!\n", filename
.c_str(), linenum
);
959 bool is_selected
= RTLIL::const_eq(ref_value
, buf
->bitsAsConst(), ref_signed
&& buf
->is_signed
, ref_signed
&& buf
->is_signed
, 1).as_bool();
963 selected_case
= this_genblock
;
970 if (selected_case
!= NULL
)
972 log_assert(selected_case
->type
== AST_GENBLOCK
);
973 buf
= selected_case
->clone();
975 if (!buf
->str
.empty()) {
976 std::map
<std::string
, std::string
> name_map
;
977 buf
->expand_genblock(std::string(), buf
->str
+ ".", name_map
);
980 for (size_t i
= 0; i
< buf
->children
.size(); i
++) {
981 buf
->children
[i
]->simplify(false, false, false, stage
, -1, false, false);
982 current_ast_mod
->children
.push_back(buf
->children
[i
]);
985 buf
->children
.clear();
990 did_something
= true;
993 // unroll cell arrays
994 if (type
== AST_CELLARRAY
)
996 if (!children
.at(0)->range_valid
)
997 log_error("Non-constant array range on cell array at %s:%d.\n", filename
.c_str(), linenum
);
999 newNode
= new AstNode(AST_GENBLOCK
);
1000 int num
= std::max(children
.at(0)->range_left
, children
.at(0)->range_right
) - std::min(children
.at(0)->range_left
, children
.at(0)->range_right
) + 1;
1002 for (int i
= 0; i
< num
; i
++) {
1003 int idx
= children
.at(0)->range_left
> children
.at(0)->range_right
? children
.at(0)->range_right
+ i
: children
.at(0)->range_right
- i
;
1004 AstNode
*new_cell
= children
.at(1)->clone();
1005 newNode
->children
.push_back(new_cell
);
1006 new_cell
->str
+= stringf("[%d]", idx
);
1007 if (new_cell
->type
== AST_PRIMITIVE
) {
1008 log_error("Cell arrays of primitives are currently not supported at %s:%d.\n", filename
.c_str(), linenum
);
1010 log_assert(new_cell
->children
.at(0)->type
== AST_CELLTYPE
);
1011 new_cell
->children
.at(0)->str
= stringf("$array:%d:%d:%s", i
, num
, new_cell
->children
.at(0)->str
.c_str());
1018 // replace primitives with assignmens
1019 if (type
== AST_PRIMITIVE
)
1021 if (children
.size() < 2)
1022 log_error("Insufficient number of arguments for primitive `%s' at %s:%d!\n",
1023 str
.c_str(), filename
.c_str(), linenum
);
1025 std::vector
<AstNode
*> children_list
;
1026 for (auto child
: children
) {
1027 log_assert(child
->type
== AST_ARGUMENT
);
1028 log_assert(child
->children
.size() == 1);
1029 children_list
.push_back(child
->children
[0]);
1030 child
->children
.clear();
1035 if (str
== "bufif0" || str
== "bufif1" || str
== "notif0" || str
== "notif1")
1037 if (children_list
.size() != 3)
1038 log_error("Invalid number of arguments for primitive `%s' at %s:%d!\n",
1039 str
.c_str(), filename
.c_str(), linenum
);
1041 std::vector
<RTLIL::State
> z_const(1, RTLIL::State::Sz
);
1043 AstNode
*mux_input
= children_list
.at(1);
1044 if (str
== "notif0" || str
== "notif1") {
1045 mux_input
= new AstNode(AST_BIT_NOT
, mux_input
);
1047 AstNode
*node
= new AstNode(AST_TERNARY
, children_list
.at(2));
1048 if (str
== "bufif0") {
1049 node
->children
.push_back(AstNode::mkconst_bits(z_const
, false));
1050 node
->children
.push_back(mux_input
);
1052 node
->children
.push_back(mux_input
);
1053 node
->children
.push_back(AstNode::mkconst_bits(z_const
, false));
1058 children
.push_back(children_list
.at(0));
1059 children
.push_back(node
);
1060 did_something
= true;
1064 AstNodeType op_type
= AST_NONE
;
1065 bool invert_results
= false;
1068 op_type
= AST_BIT_AND
;
1070 op_type
= AST_BIT_AND
, invert_results
= true;
1072 op_type
= AST_BIT_OR
;
1074 op_type
= AST_BIT_OR
, invert_results
= true;
1076 op_type
= AST_BIT_XOR
;
1078 op_type
= AST_BIT_XOR
, invert_results
= true;
1082 op_type
= AST_POS
, invert_results
= true;
1083 log_assert(op_type
!= AST_NONE
);
1085 AstNode
*node
= children_list
[1];
1086 if (op_type
!= AST_POS
)
1087 for (size_t i
= 2; i
< children_list
.size(); i
++)
1088 node
= new AstNode(op_type
, node
, children_list
[i
]);
1090 node
= new AstNode(AST_BIT_NOT
, node
);
1094 children
.push_back(children_list
[0]);
1095 children
.push_back(node
);
1096 did_something
= true;
1100 // replace dynamic ranges in left-hand side expressions (e.g. "foo[bar] <= 1'b1;") with
1101 // a big case block that selects the correct single-bit assignment.
1102 if (type
== AST_ASSIGN_EQ
|| type
== AST_ASSIGN_LE
) {
1103 if (children
[0]->type
!= AST_IDENTIFIER
|| children
[0]->children
.size() == 0)
1104 goto skip_dynamic_range_lvalue_expansion
;
1105 if (children
[0]->children
[0]->range_valid
|| did_something
)
1106 goto skip_dynamic_range_lvalue_expansion
;
1107 if (children
[0]->id2ast
== NULL
|| children
[0]->id2ast
->type
!= AST_WIRE
)
1108 goto skip_dynamic_range_lvalue_expansion
;
1109 if (!children
[0]->id2ast
->range_valid
)
1110 goto skip_dynamic_range_lvalue_expansion
;
1111 int source_width
= children
[0]->id2ast
->range_left
- children
[0]->id2ast
->range_right
+ 1;
1112 int result_width
= 1;
1113 AstNode
*shift_expr
= NULL
;
1114 AstNode
*range
= children
[0]->children
[0];
1115 if (range
->children
.size() == 1) {
1116 shift_expr
= range
->children
[0]->clone();
1118 shift_expr
= range
->children
[1]->clone();
1119 AstNode
*left_at_zero_ast
= range
->children
[0]->clone();
1120 AstNode
*right_at_zero_ast
= range
->children
[1]->clone();
1121 while (left_at_zero_ast
->simplify(true, true, false, stage
, -1, false, false)) { }
1122 while (right_at_zero_ast
->simplify(true, true, false, stage
, -1, false, false)) { }
1123 if (left_at_zero_ast
->type
!= AST_CONSTANT
|| right_at_zero_ast
->type
!= AST_CONSTANT
)
1124 log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n",
1125 str
.c_str(), filename
.c_str(), linenum
);
1126 result_width
= left_at_zero_ast
->integer
- right_at_zero_ast
->integer
+ 1;
1128 did_something
= true;
1129 newNode
= new AstNode(AST_CASE
, shift_expr
);
1130 for (int i
= 0; i
<= source_width
-result_width
; i
++) {
1131 int start_bit
= children
[0]->id2ast
->range_right
+ i
;
1132 AstNode
*cond
= new AstNode(AST_COND
, mkconst_int(start_bit
, true));
1133 AstNode
*lvalue
= children
[0]->clone();
1134 lvalue
->delete_children();
1135 lvalue
->children
.push_back(new AstNode(AST_RANGE
,
1136 mkconst_int(start_bit
+result_width
-1, true), mkconst_int(start_bit
, true)));
1137 cond
->children
.push_back(new AstNode(AST_BLOCK
, new AstNode(type
, lvalue
, children
[1]->clone())));
1138 newNode
->children
.push_back(cond
);
1142 skip_dynamic_range_lvalue_expansion
:;
1144 if (stage
> 1 && type
== AST_ASSERT
&& current_block
!= NULL
)
1146 std::stringstream sstr
;
1147 sstr
<< "$assert$" << filename
<< ":" << linenum
<< "$" << (autoidx
++);
1148 std::string id_check
= sstr
.str() + "_CHECK", id_en
= sstr
.str() + "_EN";
1150 AstNode
*wire_check
= new AstNode(AST_WIRE
);
1151 wire_check
->str
= id_check
;
1152 current_ast_mod
->children
.push_back(wire_check
);
1153 current_scope
[wire_check
->str
] = wire_check
;
1154 while (wire_check
->simplify(true, false, false, 1, -1, false, false)) { }
1156 AstNode
*wire_en
= new AstNode(AST_WIRE
);
1157 wire_en
->str
= id_en
;
1158 current_ast_mod
->children
.push_back(wire_en
);
1159 current_ast_mod
->children
.push_back(new AstNode(AST_INITIAL
, new AstNode(AST_BLOCK
, new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), AstNode::mkconst_int(0, false, 1)))));
1160 current_ast_mod
->children
.back()->children
[0]->children
[0]->children
[0]->str
= id_en
;
1161 current_scope
[wire_en
->str
] = wire_en
;
1162 while (wire_en
->simplify(true, false, false, 1, -1, false, false)) { }
1164 std::vector
<RTLIL::State
> x_bit
;
1165 x_bit
.push_back(RTLIL::State::Sx
);
1167 AstNode
*assign_check
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_bits(x_bit
, false));
1168 assign_check
->children
[0]->str
= id_check
;
1170 AstNode
*assign_en
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_int(0, false, 1));
1171 assign_en
->children
[0]->str
= id_en
;
1173 AstNode
*default_signals
= new AstNode(AST_BLOCK
);
1174 default_signals
->children
.push_back(assign_check
);
1175 default_signals
->children
.push_back(assign_en
);
1176 current_top_block
->children
.insert(current_top_block
->children
.begin(), default_signals
);
1178 assign_check
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), new AstNode(AST_REDUCE_BOOL
, children
[0]->clone()));
1179 assign_check
->children
[0]->str
= id_check
;
1181 assign_en
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_int(1, false, 1));
1182 assign_en
->children
[0]->str
= id_en
;
1184 newNode
= new AstNode(AST_BLOCK
);
1185 newNode
->children
.push_back(assign_check
);
1186 newNode
->children
.push_back(assign_en
);
1188 AstNode
*assertnode
= new AstNode(AST_ASSERT
);
1189 assertnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
1190 assertnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
1191 assertnode
->children
[0]->str
= id_check
;
1192 assertnode
->children
[1]->str
= id_en
;
1193 assertnode
->attributes
.swap(attributes
);
1194 current_ast_mod
->children
.push_back(assertnode
);
1199 if (stage
> 1 && type
== AST_ASSERT
&& children
.size() == 1)
1201 children
[0] = new AstNode(AST_REDUCE_BOOL
, children
[0]->clone());
1202 children
.push_back(mkconst_int(1, false, 1));
1203 did_something
= true;
1206 // found right-hand side identifier for memory -> replace with memory read port
1207 if (stage
> 1 && type
== AST_IDENTIFIER
&& id2ast
!= NULL
&& id2ast
->type
== AST_MEMORY
&& !in_lvalue
&&
1208 children
[0]->type
== AST_RANGE
&& children
[0]->children
.size() == 1) {
1209 newNode
= new AstNode(AST_MEMRD
, children
[0]->children
[0]->clone());
1211 newNode
->id2ast
= id2ast
;
1215 // assignment with memory in left-hand side expression -> replace with memory write port
1216 if (stage
> 1 && (type
== AST_ASSIGN_EQ
|| type
== AST_ASSIGN_LE
) && children
[0]->type
== AST_IDENTIFIER
&&
1217 children
[0]->id2ast
&& children
[0]->id2ast
->type
== AST_MEMORY
&& children
[0]->id2ast
->children
.size() >= 2 &&
1218 children
[0]->id2ast
->children
[0]->range_valid
&& children
[0]->id2ast
->children
[1]->range_valid
&&
1219 (children
[0]->children
.size() == 1 || children
[0]->children
.size() == 2) && children
[0]->children
[0]->type
== AST_RANGE
)
1221 std::stringstream sstr
;
1222 sstr
<< "$memwr$" << children
[0]->str
<< "$" << filename
<< ":" << linenum
<< "$" << (autoidx
++);
1223 std::string id_addr
= sstr
.str() + "_ADDR", id_data
= sstr
.str() + "_DATA", id_en
= sstr
.str() + "_EN";
1225 if (type
== AST_ASSIGN_EQ
)
1226 log("Warning: Blocking assignment to memory in line %s:%d is handled like a non-blocking assignment.\n",
1227 filename
.c_str(), linenum
);
1229 int mem_width
, mem_size
, addr_bits
;
1230 children
[0]->id2ast
->meminfo(mem_width
, mem_size
, addr_bits
);
1232 AstNode
*wire_addr
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(addr_bits
-1, true), mkconst_int(0, true)));
1233 wire_addr
->str
= id_addr
;
1234 current_ast_mod
->children
.push_back(wire_addr
);
1235 current_scope
[wire_addr
->str
] = wire_addr
;
1236 while (wire_addr
->simplify(true, false, false, 1, -1, false, false)) { }
1238 AstNode
*wire_data
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
1239 wire_data
->str
= id_data
;
1240 current_ast_mod
->children
.push_back(wire_data
);
1241 current_scope
[wire_data
->str
] = wire_data
;
1242 while (wire_data
->simplify(true, false, false, 1, -1, false, false)) { }
1244 AstNode
*wire_en
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
1245 wire_en
->str
= id_en
;
1246 current_ast_mod
->children
.push_back(wire_en
);
1247 current_scope
[wire_en
->str
] = wire_en
;
1248 while (wire_en
->simplify(true, false, false, 1, -1, false, false)) { }
1250 std::vector
<RTLIL::State
> x_bits_addr
, x_bits_data
, set_bits_en
;
1251 for (int i
= 0; i
< addr_bits
; i
++)
1252 x_bits_addr
.push_back(RTLIL::State::Sx
);
1253 for (int i
= 0; i
< mem_width
; i
++)
1254 x_bits_data
.push_back(RTLIL::State::Sx
);
1255 for (int i
= 0; i
< mem_width
; i
++)
1256 set_bits_en
.push_back(RTLIL::State::S1
);
1258 AstNode
*assign_addr
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_bits(x_bits_addr
, false));
1259 assign_addr
->children
[0]->str
= id_addr
;
1261 AstNode
*assign_data
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_bits(x_bits_data
, false));
1262 assign_data
->children
[0]->str
= id_data
;
1264 AstNode
*assign_en
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_int(0, false, mem_width
));
1265 assign_en
->children
[0]->str
= id_en
;
1267 AstNode
*default_signals
= new AstNode(AST_BLOCK
);
1268 default_signals
->children
.push_back(assign_addr
);
1269 default_signals
->children
.push_back(assign_data
);
1270 default_signals
->children
.push_back(assign_en
);
1271 current_top_block
->children
.insert(current_top_block
->children
.begin(), default_signals
);
1273 assign_addr
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), children
[0]->children
[0]->children
[0]->clone());
1274 assign_addr
->children
[0]->str
= id_addr
;
1276 if (children
[0]->children
.size() == 2)
1278 if (children
[0]->children
[1]->range_valid
)
1280 int offset
= children
[0]->children
[1]->range_right
;
1281 int width
= children
[0]->children
[1]->range_left
- offset
+ 1;
1283 std::vector
<RTLIL::State
> padding_x(offset
, RTLIL::State::Sx
);
1285 for (int i
= 0; i
< mem_width
; i
++)
1286 set_bits_en
[i
] = offset
<= i
&& i
< offset
+width
? RTLIL::State::S1
: RTLIL::State::S0
;
1288 assign_data
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
),
1289 new AstNode(AST_CONCAT
, mkconst_bits(padding_x
, false), children
[1]->clone()));
1290 assign_data
->children
[0]->str
= id_data
;
1292 assign_en
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_bits(set_bits_en
, false));
1293 assign_en
->children
[0]->str
= id_en
;
1297 AstNode
*the_range
= children
[0]->children
[1];
1298 AstNode
*left_at_zero_ast
= the_range
->children
[0]->clone();
1299 AstNode
*right_at_zero_ast
= the_range
->children
.size() >= 2 ? the_range
->children
[1]->clone() : left_at_zero_ast
->clone();
1300 AstNode
*offset_ast
= right_at_zero_ast
->clone();
1302 while (left_at_zero_ast
->simplify(true, true, false, 1, -1, false, false)) { }
1303 while (right_at_zero_ast
->simplify(true, true, false, 1, -1, false, false)) { }
1304 if (left_at_zero_ast
->type
!= AST_CONSTANT
|| right_at_zero_ast
->type
!= AST_CONSTANT
)
1305 log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n", str
.c_str(), filename
.c_str(), linenum
);
1306 int width
= left_at_zero_ast
->integer
- right_at_zero_ast
->integer
+ 1;
1308 for (int i
= 0; i
< mem_width
; i
++)
1309 set_bits_en
[i
] = i
< width
? RTLIL::State::S1
: RTLIL::State::S0
;
1311 assign_data
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
),
1312 new AstNode(AST_SHIFT_LEFT
, children
[1]->clone(), offset_ast
->clone()));
1313 assign_data
->children
[0]->str
= id_data
;
1315 assign_en
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
),
1316 new AstNode(AST_SHIFT_LEFT
, mkconst_bits(set_bits_en
, false), offset_ast
->clone()));
1317 assign_en
->children
[0]->str
= id_en
;
1319 delete left_at_zero_ast
;
1320 delete right_at_zero_ast
;
1326 assign_data
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), children
[1]->clone());
1327 assign_data
->children
[0]->str
= id_data
;
1329 assign_en
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_bits(set_bits_en
, false));
1330 assign_en
->children
[0]->str
= id_en
;
1333 newNode
= new AstNode(AST_BLOCK
);
1334 newNode
->children
.push_back(assign_addr
);
1335 newNode
->children
.push_back(assign_data
);
1336 newNode
->children
.push_back(assign_en
);
1338 AstNode
*wrnode
= new AstNode(AST_MEMWR
);
1339 wrnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
1340 wrnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
1341 wrnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
1342 wrnode
->str
= children
[0]->str
;
1343 wrnode
->children
[0]->str
= id_addr
;
1344 wrnode
->children
[1]->str
= id_data
;
1345 wrnode
->children
[2]->str
= id_en
;
1346 current_ast_mod
->children
.push_back(wrnode
);
1351 // replace function and task calls with the code from the function or task
1352 if ((type
== AST_FCALL
|| type
== AST_TCALL
) && !str
.empty())
1354 if (type
== AST_FCALL
)
1356 if (str
== "\\$clog2")
1358 if (children
.size() != 1)
1359 log_error("System function %s got %d arguments, expected 1 at %s:%d.\n",
1360 RTLIL::unescape_id(str
).c_str(), int(children
.size()), filename
.c_str(), linenum
);
1362 AstNode
*buf
= children
[0]->clone();
1363 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
, false)) { }
1364 if (buf
->type
!= AST_CONSTANT
)
1365 log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str
.c_str(), filename
.c_str(), linenum
);
1367 RTLIL::Const arg_value
= buf
->bitsAsConst();
1370 uint32_t result
= 0;
1371 for (size_t i
= 0; i
< arg_value
.bits
.size(); i
++)
1372 if (arg_value
.bits
.at(i
) == RTLIL::State::S1
)
1375 newNode
= mkconst_int(result
, false);
1379 if (str
== "\\$ln" || str
== "\\$log10" || str
== "\\$exp" || str
== "\\$sqrt" || str
== "\\$pow" ||
1380 str
== "\\$floor" || str
== "\\$ceil" || str
== "\\$sin" || str
== "\\$cos" || str
== "\\$tan" ||
1381 str
== "\\$asin" || str
== "\\$acos" || str
== "\\$atan" || str
== "\\$atan2" || str
== "\\$hypot" ||
1382 str
== "\\$sinh" || str
== "\\$cosh" || str
== "\\$tanh" || str
== "\\$asinh" || str
== "\\$acosh" || str
== "\\$atanh")
1384 bool func_with_two_arguments
= str
== "\\$pow" || str
== "\\$atan2" || str
== "\\$hypot";
1385 double x
= 0, y
= 0;
1387 if (func_with_two_arguments
) {
1388 if (children
.size() != 2)
1389 log_error("System function %s got %d arguments, expected 2 at %s:%d.\n",
1390 RTLIL::unescape_id(str
).c_str(), int(children
.size()), filename
.c_str(), linenum
);
1392 if (children
.size() != 1)
1393 log_error("System function %s got %d arguments, expected 1 at %s:%d.\n",
1394 RTLIL::unescape_id(str
).c_str(), int(children
.size()), filename
.c_str(), linenum
);
1397 if (children
.size() >= 1) {
1398 while (children
[0]->simplify(true, false, false, stage
, width_hint
, sign_hint
, false)) { }
1399 if (!children
[0]->isConst())
1400 log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n",
1401 RTLIL::unescape_id(str
).c_str(), filename
.c_str(), linenum
);
1402 int child_width_hint
= width_hint
;
1403 bool child_sign_hint
= sign_hint
;
1404 children
[0]->detectSignWidth(child_width_hint
, child_sign_hint
);
1405 x
= children
[0]->asReal(child_sign_hint
);
1408 if (children
.size() >= 2) {
1409 while (children
[1]->simplify(true, false, false, stage
, width_hint
, sign_hint
, false)) { }
1410 if (!children
[1]->isConst())
1411 log_error("Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n",
1412 RTLIL::unescape_id(str
).c_str(), filename
.c_str(), linenum
);
1413 int child_width_hint
= width_hint
;
1414 bool child_sign_hint
= sign_hint
;
1415 children
[1]->detectSignWidth(child_width_hint
, child_sign_hint
);
1416 y
= children
[1]->asReal(child_sign_hint
);
1419 newNode
= new AstNode(AST_REALVALUE
);
1420 if (str
== "\\$ln") newNode
->realvalue
= ::log(x
);
1421 else if (str
== "\\$log10") newNode
->realvalue
= ::log10(x
);
1422 else if (str
== "\\$exp") newNode
->realvalue
= ::exp(x
);
1423 else if (str
== "\\$sqrt") newNode
->realvalue
= ::sqrt(x
);
1424 else if (str
== "\\$pow") newNode
->realvalue
= ::pow(x
, y
);
1425 else if (str
== "\\$floor") newNode
->realvalue
= ::floor(x
);
1426 else if (str
== "\\$ceil") newNode
->realvalue
= ::ceil(x
);
1427 else if (str
== "\\$sin") newNode
->realvalue
= ::sin(x
);
1428 else if (str
== "\\$cos") newNode
->realvalue
= ::cos(x
);
1429 else if (str
== "\\$tan") newNode
->realvalue
= ::tan(x
);
1430 else if (str
== "\\$asin") newNode
->realvalue
= ::asin(x
);
1431 else if (str
== "\\$acos") newNode
->realvalue
= ::acos(x
);
1432 else if (str
== "\\$atan") newNode
->realvalue
= ::atan(x
);
1433 else if (str
== "\\$atan2") newNode
->realvalue
= ::atan2(x
, y
);
1434 else if (str
== "\\$hypot") newNode
->realvalue
= ::hypot(x
, y
);
1435 else if (str
== "\\$sinh") newNode
->realvalue
= ::sinh(x
);
1436 else if (str
== "\\$cosh") newNode
->realvalue
= ::cosh(x
);
1437 else if (str
== "\\$tanh") newNode
->realvalue
= ::tanh(x
);
1438 else if (str
== "\\$asinh") newNode
->realvalue
= ::asinh(x
);
1439 else if (str
== "\\$acosh") newNode
->realvalue
= ::acosh(x
);
1440 else if (str
== "\\$atanh") newNode
->realvalue
= ::atanh(x
);
1445 if (current_scope
.count(str
) == 0 || current_scope
[str
]->type
!= AST_FUNCTION
)
1446 log_error("Can't resolve function name `%s' at %s:%d.\n", str
.c_str(), filename
.c_str(), linenum
);
1448 if (type
== AST_TCALL
) {
1449 if (current_scope
.count(str
) == 0 || current_scope
[str
]->type
!= AST_TASK
)
1450 log_error("Can't resolve task name `%s' at %s:%d.\n", str
.c_str(), filename
.c_str(), linenum
);
1453 AstNode
*decl
= current_scope
[str
];
1455 std::stringstream sstr
;
1456 sstr
<< "$func$" << str
<< "$" << filename
<< ":" << linenum
<< "$" << (autoidx
++) << "$";
1457 std::string prefix
= sstr
.str();
1459 bool recommend_const_eval
= false;
1460 bool require_const_eval
= in_param
? false : has_const_only_constructs(recommend_const_eval
);
1461 if ((in_param
|| recommend_const_eval
|| require_const_eval
) && !decl
->attributes
.count("\\via_celltype"))
1463 bool all_args_const
= true;
1464 for (auto child
: children
) {
1465 while (child
->simplify(true, false, false, 1, -1, false, true)) { }
1466 if (child
->type
!= AST_CONSTANT
)
1467 all_args_const
= false;
1470 if (all_args_const
) {
1471 AstNode
*func_workspace
= current_scope
[str
]->clone();
1472 newNode
= func_workspace
->eval_const_function(this);
1473 delete func_workspace
;
1478 log_error("Non-constant function call in constant expression at %s:%d.\n", filename
.c_str(), linenum
);
1479 if (require_const_eval
)
1480 log_error("Function %s can only be called with constant arguments at %s:%d.\n", str
.c_str(), filename
.c_str(), linenum
);
1483 size_t arg_count
= 0;
1484 std::map
<std::string
, std::string
> replace_rules
;
1486 if (current_block
== NULL
)
1488 log_assert(type
== AST_FCALL
);
1490 AstNode
*wire
= NULL
;
1491 for (auto child
: decl
->children
)
1492 if (child
->type
== AST_WIRE
&& child
->str
== str
)
1493 wire
= child
->clone();
1494 log_assert(wire
!= NULL
);
1496 wire
->str
= prefix
+ str
;
1498 wire
->is_input
= false;
1499 wire
->is_output
= false;
1501 current_ast_mod
->children
.push_back(wire
);
1502 while (wire
->simplify(true, false, false, 1, -1, false, false)) { }
1504 AstNode
*lvalue
= new AstNode(AST_IDENTIFIER
);
1505 lvalue
->str
= wire
->str
;
1507 AstNode
*always
= new AstNode(AST_ALWAYS
, new AstNode(AST_BLOCK
,
1508 new AstNode(AST_ASSIGN_EQ
, lvalue
, clone())));
1509 current_ast_mod
->children
.push_back(always
);
1511 goto replace_fcall_with_id
;
1514 if (decl
->attributes
.count("\\via_celltype"))
1516 std::string celltype
= decl
->attributes
.at("\\via_celltype")->asAttrConst().decode_string();
1517 std::string outport
= str
;
1519 if (celltype
.find(' ') != std::string::npos
) {
1520 int pos
= celltype
.find(' ');
1521 outport
= RTLIL::escape_id(celltype
.substr(pos
+1));
1522 celltype
= RTLIL::escape_id(celltype
.substr(0, pos
));
1524 celltype
= RTLIL::escape_id(celltype
);
1526 AstNode
*cell
= new AstNode(AST_CELL
, new AstNode(AST_CELLTYPE
));
1527 cell
->str
= prefix
.substr(0, SIZE(prefix
)-1);
1528 cell
->children
[0]->str
= celltype
;
1530 for (auto attr
: decl
->attributes
)
1531 if (attr
.first
.str().rfind("\\via_celltype_defparam_", 0) == 0)
1533 AstNode
*cell_arg
= new AstNode(AST_PARASET
, attr
.second
->clone());
1534 cell_arg
->str
= RTLIL::escape_id(attr
.first
.str().substr(strlen("\\via_celltype_defparam_")));
1535 cell
->children
.push_back(cell_arg
);
1538 for (auto child
: decl
->children
)
1539 if (child
->type
== AST_WIRE
&& (child
->is_input
|| child
->is_output
|| (type
== AST_FCALL
&& child
->str
== str
)))
1541 AstNode
*wire
= child
->clone();
1542 wire
->str
= prefix
+ wire
->str
;
1544 wire
->is_input
= false;
1545 wire
->is_output
= false;
1546 current_ast_mod
->children
.push_back(wire
);
1547 while (wire
->simplify(true, false, false, 1, -1, false, false)) { }
1549 AstNode
*wire_id
= new AstNode(AST_IDENTIFIER
);
1550 wire_id
->str
= wire
->str
;
1552 if ((child
->is_input
|| child
->is_output
) && arg_count
< children
.size())
1554 AstNode
*arg
= children
[arg_count
++]->clone();
1555 AstNode
*assign
= child
->is_input
?
1556 new AstNode(AST_ASSIGN_EQ
, wire_id
, arg
) :
1557 new AstNode(AST_ASSIGN_EQ
, arg
, wire_id
);
1559 for (auto it
= current_block
->children
.begin(); it
!= current_block
->children
.end(); it
++) {
1560 if (*it
!= current_block_child
)
1562 current_block
->children
.insert(it
, assign
);
1567 AstNode
*cell_arg
= new AstNode(AST_ARGUMENT
, wire_id
->clone());
1568 cell_arg
->str
= child
->str
== str
? outport
: child
->str
;
1569 cell
->children
.push_back(cell_arg
);
1572 current_ast_mod
->children
.push_back(cell
);
1573 goto replace_fcall_with_id
;
1576 for (auto child
: decl
->children
)
1577 if (child
->type
== AST_WIRE
)
1579 AstNode
*wire
= child
->clone();
1580 wire
->str
= prefix
+ wire
->str
;
1582 wire
->is_input
= false;
1583 wire
->is_output
= false;
1584 current_ast_mod
->children
.push_back(wire
);
1585 while (wire
->simplify(true, false, false, 1, -1, false, false)) { }
1587 replace_rules
[child
->str
] = wire
->str
;
1589 if ((child
->is_input
|| child
->is_output
) && arg_count
< children
.size())
1591 AstNode
*arg
= children
[arg_count
++]->clone();
1592 AstNode
*wire_id
= new AstNode(AST_IDENTIFIER
);
1593 wire_id
->str
= wire
->str
;
1594 AstNode
*assign
= child
->is_input
?
1595 new AstNode(AST_ASSIGN_EQ
, wire_id
, arg
) :
1596 new AstNode(AST_ASSIGN_EQ
, arg
, wire_id
);
1598 for (auto it
= current_block
->children
.begin(); it
!= current_block
->children
.end(); it
++) {
1599 if (*it
!= current_block_child
)
1601 current_block
->children
.insert(it
, assign
);
1607 for (auto child
: decl
->children
)
1608 if (child
->type
!= AST_WIRE
)
1610 AstNode
*stmt
= child
->clone();
1611 stmt
->replace_ids(prefix
, replace_rules
);
1613 for (auto it
= current_block
->children
.begin(); it
!= current_block
->children
.end(); it
++) {
1614 if (*it
!= current_block_child
)
1616 current_block
->children
.insert(it
, stmt
);
1621 replace_fcall_with_id
:
1622 if (type
== AST_FCALL
) {
1624 type
= AST_IDENTIFIER
;
1627 if (type
== AST_TCALL
)
1629 did_something
= true;
1632 // perform const folding when activated
1636 std::vector
<RTLIL::State
> tmp_bits
;
1637 RTLIL::Const (*const_func
)(const RTLIL::Const
&, const RTLIL::Const
&, bool, bool, int);
1638 RTLIL::Const dummy_arg
;
1642 case AST_IDENTIFIER
:
1643 if (current_scope
.count(str
) > 0 && (current_scope
[str
]->type
== AST_PARAMETER
|| current_scope
[str
]->type
== AST_LOCALPARAM
)) {
1644 if (current_scope
[str
]->children
[0]->type
== AST_CONSTANT
) {
1645 if (children
.size() != 0 && children
[0]->type
== AST_RANGE
&& children
[0]->range_valid
) {
1646 std::vector
<RTLIL::State
> data
;
1647 bool param_upto
= current_scope
[str
]->range_valid
&& current_scope
[str
]->range_swapped
;
1648 int param_offset
= current_scope
[str
]->range_valid
? current_scope
[str
]->range_right
: 0;
1649 int param_width
= current_scope
[str
]->range_valid
? current_scope
[str
]->range_left
- current_scope
[str
]->range_right
+ 1 :
1650 SIZE(current_scope
[str
]->children
[0]->bits
);
1651 int tmp_range_left
= children
[0]->range_left
, tmp_range_right
= children
[0]->range_right
;
1653 tmp_range_left
= (param_width
+ 2*param_offset
) - children
[0]->range_right
- 1;
1654 tmp_range_right
= (param_width
+ 2*param_offset
) - children
[0]->range_left
- 1;
1656 for (int i
= tmp_range_right
; i
<= tmp_range_left
; i
++) {
1657 int index
= i
- param_offset
;
1658 if (0 <= index
&& index
< param_width
)
1659 data
.push_back(current_scope
[str
]->children
[0]->bits
[index
]);
1661 data
.push_back(RTLIL::State::Sx
);
1663 newNode
= mkconst_bits(data
, false);
1665 if (children
.size() == 0)
1666 newNode
= current_scope
[str
]->children
[0]->clone();
1668 if (current_scope
[str
]->children
[0]->isConst())
1669 newNode
= current_scope
[str
]->children
[0]->clone();
1671 else if (at_zero
&& current_scope
.count(str
) > 0 && (current_scope
[str
]->type
== AST_WIRE
|| current_scope
[str
]->type
== AST_AUTOWIRE
)) {
1672 newNode
= mkconst_int(0, sign_hint
, width_hint
);
1676 if (children
[0]->type
== AST_CONSTANT
) {
1677 RTLIL::Const y
= RTLIL::const_not(children
[0]->bitsAsConst(width_hint
, sign_hint
), dummy_arg
, sign_hint
, false, width_hint
);
1678 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1682 case AST_TO_UNSIGNED
:
1683 if (children
[0]->type
== AST_CONSTANT
) {
1684 RTLIL::Const y
= children
[0]->bitsAsConst(width_hint
, sign_hint
);
1685 newNode
= mkconst_bits(y
.bits
, type
== AST_TO_SIGNED
);
1688 if (0) { case AST_BIT_AND
: const_func
= RTLIL::const_and
; }
1689 if (0) { case AST_BIT_OR
: const_func
= RTLIL::const_or
; }
1690 if (0) { case AST_BIT_XOR
: const_func
= RTLIL::const_xor
; }
1691 if (0) { case AST_BIT_XNOR
: const_func
= RTLIL::const_xnor
; }
1692 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1693 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(width_hint
, sign_hint
),
1694 children
[1]->bitsAsConst(width_hint
, sign_hint
), sign_hint
, sign_hint
, width_hint
);
1695 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1698 if (0) { case AST_REDUCE_AND
: const_func
= RTLIL::const_reduce_and
; }
1699 if (0) { case AST_REDUCE_OR
: const_func
= RTLIL::const_reduce_or
; }
1700 if (0) { case AST_REDUCE_XOR
: const_func
= RTLIL::const_reduce_xor
; }
1701 if (0) { case AST_REDUCE_XNOR
: const_func
= RTLIL::const_reduce_xnor
; }
1702 if (0) { case AST_REDUCE_BOOL
: const_func
= RTLIL::const_reduce_bool
; }
1703 if (children
[0]->type
== AST_CONSTANT
) {
1704 RTLIL::Const y
= const_func(RTLIL::Const(children
[0]->bits
), dummy_arg
, false, false, -1);
1705 newNode
= mkconst_bits(y
.bits
, false);
1709 if (children
[0]->type
== AST_CONSTANT
) {
1710 RTLIL::Const y
= RTLIL::const_logic_not(RTLIL::Const(children
[0]->bits
), dummy_arg
, children
[0]->is_signed
, false, -1);
1711 newNode
= mkconst_bits(y
.bits
, false);
1713 if (children
[0]->isConst()) {
1714 newNode
= mkconst_int(children
[0]->asReal(sign_hint
) == 0, false, 1);
1717 if (0) { case AST_LOGIC_AND
: const_func
= RTLIL::const_logic_and
; }
1718 if (0) { case AST_LOGIC_OR
: const_func
= RTLIL::const_logic_or
; }
1719 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1720 RTLIL::Const y
= const_func(RTLIL::Const(children
[0]->bits
), RTLIL::Const(children
[1]->bits
),
1721 children
[0]->is_signed
, children
[1]->is_signed
, -1);
1722 newNode
= mkconst_bits(y
.bits
, false);
1724 if (children
[0]->isConst() && children
[1]->isConst()) {
1725 if (type
== AST_LOGIC_AND
)
1726 newNode
= mkconst_int((children
[0]->asReal(sign_hint
) != 0) && (children
[1]->asReal(sign_hint
) != 0), false, 1);
1728 newNode
= mkconst_int((children
[0]->asReal(sign_hint
) != 0) || (children
[1]->asReal(sign_hint
) != 0), false, 1);
1731 if (0) { case AST_SHIFT_LEFT
: const_func
= RTLIL::const_shl
; }
1732 if (0) { case AST_SHIFT_RIGHT
: const_func
= RTLIL::const_shr
; }
1733 if (0) { case AST_SHIFT_SLEFT
: const_func
= RTLIL::const_sshl
; }
1734 if (0) { case AST_SHIFT_SRIGHT
: const_func
= RTLIL::const_sshr
; }
1735 if (0) { case AST_POW
: const_func
= RTLIL::const_pow
; }
1736 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1737 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(width_hint
, sign_hint
),
1738 RTLIL::Const(children
[1]->bits
), sign_hint
, type
== AST_POW
? children
[1]->is_signed
: false, width_hint
);
1739 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1741 if (type
== AST_POW
&& children
[0]->isConst() && children
[1]->isConst()) {
1742 newNode
= new AstNode(AST_REALVALUE
);
1743 newNode
->realvalue
= pow(children
[0]->asReal(sign_hint
), children
[1]->asReal(sign_hint
));
1746 if (0) { case AST_LT
: const_func
= RTLIL::const_lt
; }
1747 if (0) { case AST_LE
: const_func
= RTLIL::const_le
; }
1748 if (0) { case AST_EQ
: const_func
= RTLIL::const_eq
; }
1749 if (0) { case AST_NE
: const_func
= RTLIL::const_ne
; }
1750 if (0) { case AST_EQX
: const_func
= RTLIL::const_eqx
; }
1751 if (0) { case AST_NEX
: const_func
= RTLIL::const_nex
; }
1752 if (0) { case AST_GE
: const_func
= RTLIL::const_ge
; }
1753 if (0) { case AST_GT
: const_func
= RTLIL::const_gt
; }
1754 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1755 int cmp_width
= std::max(children
[0]->bits
.size(), children
[1]->bits
.size());
1756 bool cmp_signed
= children
[0]->is_signed
&& children
[1]->is_signed
;
1757 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(cmp_width
, cmp_signed
),
1758 children
[1]->bitsAsConst(cmp_width
, cmp_signed
), cmp_signed
, cmp_signed
, 1);
1759 newNode
= mkconst_bits(y
.bits
, false);
1761 if (children
[0]->isConst() && children
[1]->isConst()) {
1762 bool cmp_signed
= (children
[0]->type
== AST_REALVALUE
|| children
[0]->is_signed
) && (children
[1]->type
== AST_REALVALUE
|| children
[1]->is_signed
);
1764 case AST_LT
: newNode
= mkconst_int(children
[0]->asReal(cmp_signed
) < children
[1]->asReal(cmp_signed
), false, 1); break;
1765 case AST_LE
: newNode
= mkconst_int(children
[0]->asReal(cmp_signed
) <= children
[1]->asReal(cmp_signed
), false, 1); break;
1766 case AST_EQ
: newNode
= mkconst_int(children
[0]->asReal(cmp_signed
) == children
[1]->asReal(cmp_signed
), false, 1); break;
1767 case AST_NE
: newNode
= mkconst_int(children
[0]->asReal(cmp_signed
) != children
[1]->asReal(cmp_signed
), false, 1); break;
1768 case AST_EQX
: newNode
= mkconst_int(children
[0]->asReal(cmp_signed
) == children
[1]->asReal(cmp_signed
), false, 1); break;
1769 case AST_NEX
: newNode
= mkconst_int(children
[0]->asReal(cmp_signed
) != children
[1]->asReal(cmp_signed
), false, 1); break;
1770 case AST_GE
: newNode
= mkconst_int(children
[0]->asReal(cmp_signed
) >= children
[1]->asReal(cmp_signed
), false, 1); break;
1771 case AST_GT
: newNode
= mkconst_int(children
[0]->asReal(cmp_signed
) > children
[1]->asReal(cmp_signed
), false, 1); break;
1772 default: log_abort();
1776 if (0) { case AST_ADD
: const_func
= RTLIL::const_add
; }
1777 if (0) { case AST_SUB
: const_func
= RTLIL::const_sub
; }
1778 if (0) { case AST_MUL
: const_func
= RTLIL::const_mul
; }
1779 if (0) { case AST_DIV
: const_func
= RTLIL::const_div
; }
1780 if (0) { case AST_MOD
: const_func
= RTLIL::const_mod
; }
1781 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1782 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(width_hint
, sign_hint
),
1783 children
[1]->bitsAsConst(width_hint
, sign_hint
), sign_hint
, sign_hint
, width_hint
);
1784 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1786 if (children
[0]->isConst() && children
[1]->isConst()) {
1787 newNode
= new AstNode(AST_REALVALUE
);
1789 case AST_ADD
: newNode
->realvalue
= children
[0]->asReal(sign_hint
) + children
[1]->asReal(sign_hint
); break;
1790 case AST_SUB
: newNode
->realvalue
= children
[0]->asReal(sign_hint
) - children
[1]->asReal(sign_hint
); break;
1791 case AST_MUL
: newNode
->realvalue
= children
[0]->asReal(sign_hint
) * children
[1]->asReal(sign_hint
); break;
1792 case AST_DIV
: newNode
->realvalue
= children
[0]->asReal(sign_hint
) / children
[1]->asReal(sign_hint
); break;
1793 case AST_MOD
: newNode
->realvalue
= fmod(children
[0]->asReal(sign_hint
), children
[1]->asReal(sign_hint
)); break;
1794 default: log_abort();
1798 if (0) { case AST_POS
: const_func
= RTLIL::const_pos
; }
1799 if (0) { case AST_NEG
: const_func
= RTLIL::const_neg
; }
1800 if (children
[0]->type
== AST_CONSTANT
) {
1801 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(width_hint
, sign_hint
), dummy_arg
, sign_hint
, false, width_hint
);
1802 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1804 if (children
[0]->isConst()) {
1805 newNode
= new AstNode(AST_REALVALUE
);
1806 if (type
== AST_POS
)
1807 newNode
->realvalue
= +children
[0]->asReal(sign_hint
);
1809 newNode
->realvalue
= -children
[0]->asReal(sign_hint
);
1813 if (children
[0]->type
== AST_CONSTANT
&& children
[0]->bits_only_01()) {
1814 std::vector
<AstNode
*> new_children
;
1815 new_children
.push_back(children
[0]);
1816 for (int i
= 1; i
< SIZE(children
); i
++) {
1817 AstNode
*child
= children
[i
];
1818 log_assert(child
->type
== AST_COND
);
1819 for (auto v
: child
->children
) {
1820 if (v
->type
== AST_DEFAULT
)
1821 goto keep_const_cond
;
1822 if (v
->type
== AST_BLOCK
)
1824 if (v
->type
== AST_CONSTANT
&& v
->bits_only_01()) {
1825 if (v
->bits
== children
[0]->bits
) {
1826 while (i
+1 < SIZE(children
))
1827 delete children
[++i
];
1828 goto keep_const_cond
;
1832 goto keep_const_cond
;
1836 new_children
.push_back(child
);
1840 new_children
.swap(children
);
1844 if (children
[0]->isConst())
1846 bool found_sure_true
= false;
1847 bool found_maybe_true
= false;
1849 if (children
[0]->type
== AST_CONSTANT
)
1850 for (auto &bit
: children
[0]->bits
) {
1851 if (bit
== RTLIL::State::S1
)
1852 found_sure_true
= true;
1853 if (bit
> RTLIL::State::S1
)
1854 found_maybe_true
= true;
1857 found_sure_true
= children
[0]->asReal(sign_hint
) != 0;
1859 AstNode
*choice
= NULL
, *not_choice
= NULL
;
1860 if (found_sure_true
)
1861 choice
= children
[1], not_choice
= children
[2];
1862 else if (!found_maybe_true
)
1863 choice
= children
[2], not_choice
= children
[1];
1865 if (choice
!= NULL
) {
1866 if (choice
->type
== AST_CONSTANT
) {
1867 int other_width_hint
= width_hint
;
1868 bool other_sign_hint
= sign_hint
, other_real
= false;
1869 not_choice
->detectSignWidth(other_width_hint
, other_sign_hint
, &other_real
);
1871 newNode
= new AstNode(AST_REALVALUE
);
1872 choice
->detectSignWidth(width_hint
, sign_hint
);
1873 newNode
->realvalue
= choice
->asReal(sign_hint
);
1875 RTLIL::Const y
= choice
->bitsAsConst(width_hint
, sign_hint
);
1876 if (choice
->is_string
&& y
.bits
.size() % 8 == 0 && sign_hint
== false)
1877 newNode
= mkconst_str(y
.bits
);
1879 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1882 if (choice
->isConst()) {
1883 newNode
= choice
->clone();
1885 } else if (children
[1]->type
== AST_CONSTANT
&& children
[2]->type
== AST_CONSTANT
) {
1886 RTLIL::Const a
= children
[1]->bitsAsConst(width_hint
, sign_hint
);
1887 RTLIL::Const b
= children
[2]->bitsAsConst(width_hint
, sign_hint
);
1888 log_assert(a
.bits
.size() == b
.bits
.size());
1889 for (size_t i
= 0; i
< a
.bits
.size(); i
++)
1890 if (a
.bits
[i
] != b
.bits
[i
])
1891 a
.bits
[i
] = RTLIL::State::Sx
;
1892 newNode
= mkconst_bits(a
.bits
, sign_hint
);
1893 } else if (children
[1]->isConst() && children
[2]->isConst()) {
1894 newNode
= new AstNode(AST_REALVALUE
);
1895 if (children
[1]->asReal(sign_hint
) == children
[2]->asReal(sign_hint
))
1896 newNode
->realvalue
= children
[1]->asReal(sign_hint
);
1898 // IEEE Std 1800-2012 Sec. 11.4.11 states that the entry in Table 7-1 for
1899 // the data type in question should be returned if the ?: is ambiguous. The
1900 // value in Table 7-1 for the 'real' type is 0.0.
1901 newNode
->realvalue
= 0.0;
1906 string_op
= !children
.empty();
1907 for (auto it
= children
.begin(); it
!= children
.end(); it
++) {
1908 if ((*it
)->type
!= AST_CONSTANT
)
1910 if (!(*it
)->is_string
)
1912 tmp_bits
.insert(tmp_bits
.end(), (*it
)->bits
.begin(), (*it
)->bits
.end());
1914 newNode
= string_op
? mkconst_str(tmp_bits
) : mkconst_bits(tmp_bits
, false);
1917 if (children
.at(0)->type
!= AST_CONSTANT
|| children
.at(1)->type
!= AST_CONSTANT
)
1919 for (int i
= 0; i
< children
[0]->bitsAsConst().as_int(); i
++)
1920 tmp_bits
.insert(tmp_bits
.end(), children
.at(1)->bits
.begin(), children
.at(1)->bits
.end());
1921 newNode
= children
.at(1)->is_string
? mkconst_str(tmp_bits
) : mkconst_bits(tmp_bits
, false);
1929 // if any of the above set 'newNode' -> use 'newNode' as template to update 'this'
1932 // fprintf(stderr, "----\n");
1933 // dumpAst(stderr, "- ");
1934 // newNode->dumpAst(stderr, "+ ");
1935 log_assert(newNode
!= NULL
);
1936 newNode
->filename
= filename
;
1937 newNode
->linenum
= linenum
;
1938 newNode
->cloneInto(this);
1940 did_something
= true;
1946 return did_something
;
1949 static void replace_result_wire_name_in_function(AstNode
*node
, std::string
&from
, std::string
&to
)
1951 for (auto &it
: node
->children
)
1952 replace_result_wire_name_in_function(it
, from
, to
);
1953 if (node
->str
== from
)
1957 // annotate the names of all wires and other named objects in a generate block
1958 void AstNode::expand_genblock(std::string index_var
, std::string prefix
, std::map
<std::string
, std::string
> &name_map
)
1960 if (!index_var
.empty() && type
== AST_IDENTIFIER
&& str
== index_var
) {
1961 current_scope
[index_var
]->children
[0]->cloneInto(this);
1965 if ((type
== AST_IDENTIFIER
|| type
== AST_FCALL
|| type
== AST_TCALL
) && name_map
.count(str
) > 0)
1966 str
= name_map
[str
];
1968 std::map
<std::string
, std::string
> backup_name_map
;
1970 for (size_t i
= 0; i
< children
.size(); i
++) {
1971 AstNode
*child
= children
[i
];
1972 if (child
->type
== AST_WIRE
|| child
->type
== AST_MEMORY
|| child
->type
== AST_PARAMETER
|| child
->type
== AST_LOCALPARAM
||
1973 child
->type
== AST_FUNCTION
|| child
->type
== AST_TASK
|| child
->type
== AST_CELL
) {
1974 if (backup_name_map
.size() == 0)
1975 backup_name_map
= name_map
;
1976 std::string new_name
= prefix
[0] == '\\' ? prefix
.substr(1) : prefix
;
1977 size_t pos
= child
->str
.rfind('.');
1978 if (pos
== std::string::npos
)
1979 pos
= child
->str
[0] == '\\' ? 1 : 0;
1982 new_name
= child
->str
.substr(0, pos
) + new_name
+ child
->str
.substr(pos
);
1983 if (new_name
[0] != '$' && new_name
[0] != '\\')
1984 new_name
= prefix
[0] + new_name
;
1985 name_map
[child
->str
] = new_name
;
1986 if (child
->type
== AST_FUNCTION
)
1987 replace_result_wire_name_in_function(child
, child
->str
, new_name
);
1989 child
->str
= new_name
;
1990 current_scope
[new_name
] = child
;
1994 for (size_t i
= 0; i
< children
.size(); i
++) {
1995 AstNode
*child
= children
[i
];
1996 if (child
->type
!= AST_FUNCTION
&& child
->type
!= AST_TASK
&& child
->type
!= AST_PREFIX
)
1997 child
->expand_genblock(index_var
, prefix
, name_map
);
2000 if (backup_name_map
.size() > 0)
2001 name_map
.swap(backup_name_map
);
2004 // rename stuff (used when tasks of functions are instanciated)
2005 void AstNode::replace_ids(const std::string
&prefix
, const std::map
<std::string
, std::string
> &rules
)
2007 if (type
== AST_BLOCK
)
2009 std::map
<std::string
, std::string
> new_rules
= rules
;
2010 std::string new_prefix
= prefix
+ str
;
2012 for (auto child
: children
)
2013 if (child
->type
== AST_WIRE
) {
2014 new_rules
[child
->str
] = new_prefix
+ child
->str
;
2015 child
->str
= new_prefix
+ child
->str
;
2018 for (auto child
: children
)
2019 if (child
->type
!= AST_WIRE
)
2020 child
->replace_ids(new_prefix
, new_rules
);
2024 if (type
== AST_IDENTIFIER
&& rules
.count(str
) > 0)
2025 str
= rules
.at(str
);
2026 for (auto child
: children
)
2027 child
->replace_ids(prefix
, rules
);
2031 // helper function for mem2reg_as_needed_pass1
2032 static void mark_memories_assign_lhs_complex(std::map
<AstNode
*, std::set
<std::string
>> &mem2reg_places
,
2033 std::map
<AstNode
*, uint32_t> &mem2reg_candidates
, AstNode
*that
)
2035 for (auto &child
: that
->children
)
2036 mark_memories_assign_lhs_complex(mem2reg_places
, mem2reg_candidates
, child
);
2038 if (that
->type
== AST_IDENTIFIER
&& that
->id2ast
&& that
->id2ast
->type
== AST_MEMORY
) {
2039 AstNode
*mem
= that
->id2ast
;
2040 if (!(mem2reg_candidates
[mem
] & AstNode::MEM2REG_FL_CMPLX_LHS
))
2041 mem2reg_places
[mem
].insert(stringf("%s:%d", that
->filename
.c_str(), that
->linenum
));
2042 mem2reg_candidates
[mem
] |= AstNode::MEM2REG_FL_CMPLX_LHS
;
2046 // find memories that should be replaced by registers
2047 void AstNode::mem2reg_as_needed_pass1(std::map
<AstNode
*, std::set
<std::string
>> &mem2reg_places
,
2048 std::map
<AstNode
*, uint32_t> &mem2reg_candidates
, std::map
<AstNode
*, uint32_t> &proc_flags
, uint32_t &flags
)
2050 uint32_t children_flags
= 0;
2051 int ignore_children_counter
= 0;
2053 if (type
== AST_ASSIGN
|| type
== AST_ASSIGN_LE
|| type
== AST_ASSIGN_EQ
)
2055 // mark all memories that are used in a complex expression on the left side of an assignment
2056 for (auto &lhs_child
: children
[0]->children
)
2057 mark_memories_assign_lhs_complex(mem2reg_places
, mem2reg_candidates
, lhs_child
);
2059 if (children
[0]->type
== AST_IDENTIFIER
&& children
[0]->id2ast
&& children
[0]->id2ast
->type
== AST_MEMORY
)
2061 AstNode
*mem
= children
[0]->id2ast
;
2063 // activate mem2reg if this is assigned in an async proc
2064 if (flags
& AstNode::MEM2REG_FL_ASYNC
) {
2065 if (!(mem2reg_candidates
[mem
] & AstNode::MEM2REG_FL_SET_ASYNC
))
2066 mem2reg_places
[mem
].insert(stringf("%s:%d", filename
.c_str(), linenum
));
2067 mem2reg_candidates
[mem
] |= AstNode::MEM2REG_FL_SET_ASYNC
;
2070 // remember if this is assigned blocking (=)
2071 if (type
== AST_ASSIGN_EQ
) {
2072 if (!(proc_flags
[mem
] & AstNode::MEM2REG_FL_EQ1
))
2073 mem2reg_places
[mem
].insert(stringf("%s:%d", filename
.c_str(), linenum
));
2074 proc_flags
[mem
] |= AstNode::MEM2REG_FL_EQ1
;
2077 // remember where this is
2078 if (flags
& MEM2REG_FL_INIT
) {
2079 if (!(mem2reg_candidates
[mem
] & AstNode::MEM2REG_FL_SET_INIT
))
2080 mem2reg_places
[mem
].insert(stringf("%s:%d", filename
.c_str(), linenum
));
2081 mem2reg_candidates
[mem
] |= AstNode::MEM2REG_FL_SET_INIT
;
2083 if (!(mem2reg_candidates
[mem
] & AstNode::MEM2REG_FL_SET_ELSE
))
2084 mem2reg_places
[mem
].insert(stringf("%s:%d", filename
.c_str(), linenum
));
2085 mem2reg_candidates
[mem
] |= AstNode::MEM2REG_FL_SET_ELSE
;
2089 ignore_children_counter
= 1;
2092 if (type
== AST_IDENTIFIER
&& id2ast
&& id2ast
->type
== AST_MEMORY
)
2094 AstNode
*mem
= id2ast
;
2096 // flag if used after blocking assignment (in same proc)
2097 if ((proc_flags
[mem
] & AstNode::MEM2REG_FL_EQ1
) && !(mem2reg_candidates
[mem
] & AstNode::MEM2REG_FL_EQ2
)) {
2098 mem2reg_places
[mem
].insert(stringf("%s:%d", filename
.c_str(), linenum
));
2099 mem2reg_candidates
[mem
] |= AstNode::MEM2REG_FL_EQ2
;
2103 // also activate if requested, either by using mem2reg attribute or by declaring array as 'wire' instead of 'reg'
2104 if (type
== AST_MEMORY
&& (get_bool_attribute("\\mem2reg") || (flags
& AstNode::MEM2REG_FL_ALL
) || !is_reg
))
2105 mem2reg_candidates
[this] |= AstNode::MEM2REG_FL_FORCED
;
2107 if (type
== AST_MODULE
&& get_bool_attribute("\\mem2reg"))
2108 children_flags
|= AstNode::MEM2REG_FL_ALL
;
2110 std::map
<AstNode
*, uint32_t> *proc_flags_p
= NULL
;
2112 if (type
== AST_ALWAYS
) {
2113 int count_edge_events
= 0;
2114 for (auto child
: children
)
2115 if (child
->type
== AST_POSEDGE
|| child
->type
== AST_NEGEDGE
)
2116 count_edge_events
++;
2117 if (count_edge_events
!= 1)
2118 children_flags
|= AstNode::MEM2REG_FL_ASYNC
;
2119 proc_flags_p
= new std::map
<AstNode
*, uint32_t>;
2122 if (type
== AST_INITIAL
) {
2123 children_flags
|= AstNode::MEM2REG_FL_INIT
;
2124 proc_flags_p
= new std::map
<AstNode
*, uint32_t>;
2127 uint32_t backup_flags
= flags
;
2128 flags
|= children_flags
;
2129 log_assert((flags
& ~0x000000ff) == 0);
2131 for (auto child
: children
)
2132 if (ignore_children_counter
> 0)
2133 ignore_children_counter
--;
2134 else if (proc_flags_p
)
2135 child
->mem2reg_as_needed_pass1(mem2reg_places
, mem2reg_candidates
, *proc_flags_p
, flags
);
2137 child
->mem2reg_as_needed_pass1(mem2reg_places
, mem2reg_candidates
, proc_flags
, flags
);
2139 flags
&= ~children_flags
| backup_flags
;
2142 for (auto it
: *proc_flags_p
)
2143 log_assert((it
.second
& ~0xff000000) == 0);
2144 delete proc_flags_p
;
2148 // actually replace memories with registers
2149 void AstNode::mem2reg_as_needed_pass2(std::set
<AstNode
*> &mem2reg_set
, AstNode
*mod
, AstNode
*block
)
2151 if (type
== AST_BLOCK
)
2154 if ((type
== AST_ASSIGN_LE
|| type
== AST_ASSIGN_EQ
) && block
!= NULL
&& children
[0]->id2ast
&&
2155 mem2reg_set
.count(children
[0]->id2ast
) > 0 && children
[0]->children
[0]->children
[0]->type
!= AST_CONSTANT
)
2157 std::stringstream sstr
;
2158 sstr
<< "$mem2reg_wr$" << children
[0]->str
<< "$" << filename
<< ":" << linenum
<< "$" << (autoidx
++);
2159 std::string id_addr
= sstr
.str() + "_ADDR", id_data
= sstr
.str() + "_DATA";
2161 int mem_width
, mem_size
, addr_bits
;
2162 children
[0]->id2ast
->meminfo(mem_width
, mem_size
, addr_bits
);
2164 AstNode
*wire_addr
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(addr_bits
-1, true), mkconst_int(0, true)));
2165 wire_addr
->str
= id_addr
;
2166 wire_addr
->is_reg
= true;
2167 wire_addr
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
2168 mod
->children
.push_back(wire_addr
);
2169 while (wire_addr
->simplify(true, false, false, 1, -1, false, false)) { }
2171 AstNode
*wire_data
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
2172 wire_data
->str
= id_data
;
2173 wire_data
->is_reg
= true;
2174 wire_data
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
2175 mod
->children
.push_back(wire_data
);
2176 while (wire_data
->simplify(true, false, false, 1, -1, false, false)) { }
2178 log_assert(block
!= NULL
);
2179 size_t assign_idx
= 0;
2180 while (assign_idx
< block
->children
.size() && block
->children
[assign_idx
] != this)
2182 log_assert(assign_idx
< block
->children
.size());
2184 AstNode
*assign_addr
= new AstNode(AST_ASSIGN_EQ
, new AstNode(AST_IDENTIFIER
), children
[0]->children
[0]->children
[0]->clone());
2185 assign_addr
->children
[0]->str
= id_addr
;
2186 block
->children
.insert(block
->children
.begin()+assign_idx
+1, assign_addr
);
2188 AstNode
*case_node
= new AstNode(AST_CASE
, new AstNode(AST_IDENTIFIER
));
2189 case_node
->children
[0]->str
= id_addr
;
2190 for (int i
= 0; i
< mem_size
; i
++) {
2191 if (children
[0]->children
[0]->children
[0]->type
== AST_CONSTANT
&& int(children
[0]->children
[0]->children
[0]->integer
) != i
)
2193 AstNode
*cond_node
= new AstNode(AST_COND
, AstNode::mkconst_int(i
, false, addr_bits
), new AstNode(AST_BLOCK
));
2194 AstNode
*assign_reg
= new AstNode(type
, new AstNode(AST_IDENTIFIER
), new AstNode(AST_IDENTIFIER
));
2195 if (children
[0]->children
.size() == 2)
2196 assign_reg
->children
[0]->children
.push_back(children
[0]->children
[1]->clone());
2197 assign_reg
->children
[0]->str
= stringf("%s[%d]", children
[0]->str
.c_str(), i
);
2198 assign_reg
->children
[1]->str
= id_data
;
2199 cond_node
->children
[1]->children
.push_back(assign_reg
);
2200 case_node
->children
.push_back(cond_node
);
2202 block
->children
.insert(block
->children
.begin()+assign_idx
+2, case_node
);
2204 children
[0]->delete_children();
2205 children
[0]->range_valid
= false;
2206 children
[0]->id2ast
= NULL
;
2207 children
[0]->str
= id_data
;
2208 type
= AST_ASSIGN_EQ
;
2211 if (type
== AST_IDENTIFIER
&& id2ast
&& mem2reg_set
.count(id2ast
) > 0)
2213 AstNode
*bit_part_sel
= NULL
;
2214 if (children
.size() == 2)
2215 bit_part_sel
= children
[1]->clone();
2217 if (children
[0]->children
[0]->type
== AST_CONSTANT
)
2219 int id
= children
[0]->children
[0]->integer
;
2220 str
= stringf("%s[%d]", str
.c_str(), id
);
2223 range_valid
= false;
2228 std::stringstream sstr
;
2229 sstr
<< "$mem2reg_rd$" << children
[0]->str
<< "$" << filename
<< ":" << linenum
<< "$" << (autoidx
++);
2230 std::string id_addr
= sstr
.str() + "_ADDR", id_data
= sstr
.str() + "_DATA";
2232 int mem_width
, mem_size
, addr_bits
;
2233 id2ast
->meminfo(mem_width
, mem_size
, addr_bits
);
2235 AstNode
*wire_addr
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(addr_bits
-1, true), mkconst_int(0, true)));
2236 wire_addr
->str
= id_addr
;
2237 wire_addr
->is_reg
= true;
2239 wire_addr
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
2240 mod
->children
.push_back(wire_addr
);
2241 while (wire_addr
->simplify(true, false, false, 1, -1, false, false)) { }
2243 AstNode
*wire_data
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
2244 wire_data
->str
= id_data
;
2245 wire_data
->is_reg
= true;
2247 wire_data
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
2248 mod
->children
.push_back(wire_data
);
2249 while (wire_data
->simplify(true, false, false, 1, -1, false, false)) { }
2251 AstNode
*assign_addr
= new AstNode(block
? AST_ASSIGN_EQ
: AST_ASSIGN
, new AstNode(AST_IDENTIFIER
), children
[0]->children
[0]->clone());
2252 assign_addr
->children
[0]->str
= id_addr
;
2254 AstNode
*case_node
= new AstNode(AST_CASE
, new AstNode(AST_IDENTIFIER
));
2255 case_node
->children
[0]->str
= id_addr
;
2257 for (int i
= 0; i
< mem_size
; i
++) {
2258 if (children
[0]->children
[0]->type
== AST_CONSTANT
&& int(children
[0]->children
[0]->integer
) != i
)
2260 AstNode
*cond_node
= new AstNode(AST_COND
, AstNode::mkconst_int(i
, false, addr_bits
), new AstNode(AST_BLOCK
));
2261 AstNode
*assign_reg
= new AstNode(AST_ASSIGN_EQ
, new AstNode(AST_IDENTIFIER
), new AstNode(AST_IDENTIFIER
));
2262 assign_reg
->children
[0]->str
= id_data
;
2263 assign_reg
->children
[1]->str
= stringf("%s[%d]", str
.c_str(), i
);
2264 cond_node
->children
[1]->children
.push_back(assign_reg
);
2265 case_node
->children
.push_back(cond_node
);
2268 std::vector
<RTLIL::State
> x_bits
;
2269 for (int i
= 0; i
< mem_width
; i
++)
2270 x_bits
.push_back(RTLIL::State::Sx
);
2272 AstNode
*cond_node
= new AstNode(AST_COND
, new AstNode(AST_DEFAULT
), new AstNode(AST_BLOCK
));
2273 AstNode
*assign_reg
= new AstNode(AST_ASSIGN_EQ
, new AstNode(AST_IDENTIFIER
), AstNode::mkconst_bits(x_bits
, false));
2274 assign_reg
->children
[0]->str
= id_data
;
2275 cond_node
->children
[1]->children
.push_back(assign_reg
);
2276 case_node
->children
.push_back(cond_node
);
2280 size_t assign_idx
= 0;
2281 while (assign_idx
< block
->children
.size() && !block
->children
[assign_idx
]->contains(this))
2283 log_assert(assign_idx
< block
->children
.size());
2284 block
->children
.insert(block
->children
.begin()+assign_idx
, case_node
);
2285 block
->children
.insert(block
->children
.begin()+assign_idx
, assign_addr
);
2289 AstNode
*proc
= new AstNode(AST_ALWAYS
, new AstNode(AST_BLOCK
));
2290 proc
->children
[0]->children
.push_back(case_node
);
2291 mod
->children
.push_back(proc
);
2292 mod
->children
.push_back(assign_addr
);
2296 range_valid
= false;
2302 children
.push_back(bit_part_sel
);
2305 log_assert(id2ast
== NULL
|| mem2reg_set
.count(id2ast
) == 0);
2307 auto children_list
= children
;
2308 for (size_t i
= 0; i
< children_list
.size(); i
++)
2309 children_list
[i
]->mem2reg_as_needed_pass2(mem2reg_set
, mod
, block
);
2312 // calulate memory dimensions
2313 void AstNode::meminfo(int &mem_width
, int &mem_size
, int &addr_bits
)
2315 log_assert(type
== AST_MEMORY
);
2317 mem_width
= children
[0]->range_left
- children
[0]->range_right
+ 1;
2318 mem_size
= children
[1]->range_left
- children
[1]->range_right
;
2322 mem_size
+= std::min(children
[1]->range_left
, children
[1]->range_right
) + 1;
2325 while ((1 << addr_bits
) < mem_size
)
2329 bool AstNode::has_const_only_constructs(bool &recommend_const_eval
)
2331 if (type
== AST_FOR
)
2332 recommend_const_eval
= true;
2333 if (type
== AST_WHILE
|| type
== AST_REPEAT
)
2335 if (type
== AST_FCALL
&& current_scope
.count(str
))
2336 if (current_scope
[str
]->has_const_only_constructs(recommend_const_eval
))
2338 for (auto child
: children
)
2339 if (child
->AstNode::has_const_only_constructs(recommend_const_eval
))
2344 // helper function for AstNode::eval_const_function()
2345 void AstNode::replace_variables(std::map
<std::string
, AstNode::varinfo_t
> &variables
, AstNode
*fcall
)
2347 if (type
== AST_IDENTIFIER
&& variables
.count(str
)) {
2348 int offset
= variables
.at(str
).offset
, width
= variables
.at(str
).val
.bits
.size();
2349 if (!children
.empty()) {
2350 if (children
.size() != 1 || children
.at(0)->type
!= AST_RANGE
)
2351 log_error("Memory access in constant function is not supported in %s:%d (called from %s:%d).\n",
2352 filename
.c_str(), linenum
, fcall
->filename
.c_str(), fcall
->linenum
);
2353 children
.at(0)->replace_variables(variables
, fcall
);
2354 while (simplify(true, false, false, 1, -1, false, true)) { }
2355 if (!children
.at(0)->range_valid
)
2356 log_error("Non-constant range in %s:%d (called from %s:%d).\n",
2357 filename
.c_str(), linenum
, fcall
->filename
.c_str(), fcall
->linenum
);
2358 offset
= std::min(children
.at(0)->range_left
, children
.at(0)->range_right
);
2359 width
= std::min(std::abs(children
.at(0)->range_left
- children
.at(0)->range_right
) + 1, width
);
2361 offset
-= variables
.at(str
).offset
;
2362 std::vector
<RTLIL::State
> &var_bits
= variables
.at(str
).val
.bits
;
2363 std::vector
<RTLIL::State
> new_bits(var_bits
.begin() + offset
, var_bits
.begin() + offset
+ width
);
2364 AstNode
*newNode
= mkconst_bits(new_bits
, variables
.at(str
).is_signed
);
2365 newNode
->cloneInto(this);
2370 for (auto &child
: children
)
2371 child
->replace_variables(variables
, fcall
);
2374 // evaluate functions with all-const arguments
2375 AstNode
*AstNode::eval_const_function(AstNode
*fcall
)
2377 std::map
<std::string
, AstNode
*> backup_scope
;
2378 std::map
<std::string
, AstNode::varinfo_t
> variables
;
2379 bool delete_temp_block
= false;
2380 AstNode
*block
= NULL
;
2383 for (auto child
: children
)
2385 if (child
->type
== AST_BLOCK
)
2387 log_assert(block
== NULL
);
2392 if (child
->type
== AST_WIRE
)
2394 while (child
->simplify(true, false, false, 1, -1, false, true)) { }
2395 if (!child
->range_valid
)
2396 log_error("Can't determine size of variable %s in %s:%d (called from %s:%d).\n",
2397 child
->str
.c_str(), child
->filename
.c_str(), child
->linenum
, fcall
->filename
.c_str(), fcall
->linenum
);
2398 variables
[child
->str
].val
= RTLIL::Const(RTLIL::State::Sx
, abs(child
->range_left
- child
->range_right
)+1);
2399 variables
[child
->str
].offset
= std::min(child
->range_left
, child
->range_right
);
2400 variables
[child
->str
].is_signed
= child
->is_signed
;
2401 if (child
->is_input
&& argidx
< fcall
->children
.size())
2402 variables
[child
->str
].val
= fcall
->children
.at(argidx
++)->bitsAsConst(variables
[child
->str
].val
.bits
.size());
2403 backup_scope
[child
->str
] = current_scope
[child
->str
];
2404 current_scope
[child
->str
] = child
;
2408 log_assert(block
== NULL
);
2409 delete_temp_block
= true;
2410 block
= new AstNode(AST_BLOCK
);
2411 block
->children
.push_back(child
->clone());
2414 log_assert(block
!= NULL
);
2415 log_assert(variables
.count(str
));
2417 while (!block
->children
.empty())
2419 AstNode
*stmt
= block
->children
.front();
2422 log("-----------------------------------\n");
2423 for (auto &it
: variables
)
2424 log("%20s %40s\n", it
.first
.c_str(), log_signal(it
.second
.val
));
2425 stmt
->dumpAst(NULL
, "stmt> ");
2428 if (stmt
->type
== AST_ASSIGN_EQ
)
2430 stmt
->children
.at(1)->replace_variables(variables
, fcall
);
2431 while (stmt
->simplify(true, false, false, 1, -1, false, true)) { }
2433 if (stmt
->type
!= AST_ASSIGN_EQ
)
2436 if (stmt
->children
.at(1)->type
!= AST_CONSTANT
)
2437 log_error("Non-constant expression in constant function at %s:%d (called from %s:%d). X\n",
2438 stmt
->filename
.c_str(), stmt
->linenum
, fcall
->filename
.c_str(), fcall
->linenum
);
2440 if (stmt
->children
.at(0)->type
!= AST_IDENTIFIER
)
2441 log_error("Unsupported composite left hand side in constant function at %s:%d (called from %s:%d).\n",
2442 stmt
->filename
.c_str(), stmt
->linenum
, fcall
->filename
.c_str(), fcall
->linenum
);
2444 if (!variables
.count(stmt
->children
.at(0)->str
))
2445 log_error("Assignment to non-local variable in constant function at %s:%d (called from %s:%d).\n",
2446 stmt
->filename
.c_str(), stmt
->linenum
, fcall
->filename
.c_str(), fcall
->linenum
);
2448 if (stmt
->children
.at(0)->children
.empty()) {
2449 variables
[stmt
->children
.at(0)->str
].val
= stmt
->children
.at(1)->bitsAsConst(variables
[stmt
->children
.at(0)->str
].val
.bits
.size());
2451 AstNode
*range
= stmt
->children
.at(0)->children
.at(0);
2452 if (!range
->range_valid
)
2453 log_error("Non-constant range in %s:%d (called from %s:%d).\n",
2454 range
->filename
.c_str(), range
->linenum
, fcall
->filename
.c_str(), fcall
->linenum
);
2455 int offset
= std::min(range
->range_left
, range
->range_right
);
2456 int width
= std::abs(range
->range_left
- range
->range_right
) + 1;
2457 varinfo_t
&v
= variables
[stmt
->children
.at(0)->str
];
2458 RTLIL::Const r
= stmt
->children
.at(1)->bitsAsConst(v
.val
.bits
.size());
2459 for (int i
= 0; i
< width
; i
++)
2460 v
.val
.bits
.at(i
+offset
-v
.offset
) = r
.bits
.at(i
);
2463 delete block
->children
.front();
2464 block
->children
.erase(block
->children
.begin());
2468 if (stmt
->type
== AST_FOR
)
2470 block
->children
.insert(block
->children
.begin(), stmt
->children
.at(0));
2471 stmt
->children
.at(3)->children
.push_back(stmt
->children
.at(2));
2472 stmt
->children
.erase(stmt
->children
.begin() + 2);
2473 stmt
->children
.erase(stmt
->children
.begin());
2474 stmt
->type
= AST_WHILE
;
2478 if (stmt
->type
== AST_WHILE
)
2480 AstNode
*cond
= stmt
->children
.at(0)->clone();
2481 cond
->replace_variables(variables
, fcall
);
2482 while (cond
->simplify(true, false, false, 1, -1, false, true)) { }
2484 if (cond
->type
!= AST_CONSTANT
)
2485 log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n",
2486 stmt
->filename
.c_str(), stmt
->linenum
, fcall
->filename
.c_str(), fcall
->linenum
);
2488 if (cond
->asBool()) {
2489 block
->children
.insert(block
->children
.begin(), stmt
->children
.at(1)->clone());
2491 delete block
->children
.front();
2492 block
->children
.erase(block
->children
.begin());
2499 if (stmt
->type
== AST_REPEAT
)
2501 AstNode
*num
= stmt
->children
.at(0)->clone();
2502 num
->replace_variables(variables
, fcall
);
2503 while (num
->simplify(true, false, false, 1, -1, false, true)) { }
2505 if (num
->type
!= AST_CONSTANT
)
2506 log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n",
2507 stmt
->filename
.c_str(), stmt
->linenum
, fcall
->filename
.c_str(), fcall
->linenum
);
2509 block
->children
.erase(block
->children
.begin());
2510 for (int i
= 0; i
< num
->bitsAsConst().as_int(); i
++)
2511 block
->children
.insert(block
->children
.begin(), stmt
->children
.at(1)->clone());
2518 if (stmt
->type
== AST_CASE
)
2520 AstNode
*expr
= stmt
->children
.at(0)->clone();
2521 expr
->replace_variables(variables
, fcall
);
2522 while (expr
->simplify(true, false, false, 1, -1, false, true)) { }
2524 AstNode
*sel_case
= NULL
;
2525 for (size_t i
= 1; i
< stmt
->children
.size(); i
++)
2527 bool found_match
= false;
2528 log_assert(stmt
->children
.at(i
)->type
== AST_COND
);
2530 if (stmt
->children
.at(i
)->children
.front()->type
== AST_DEFAULT
) {
2531 sel_case
= stmt
->children
.at(i
)->children
.back();
2535 for (size_t j
= 0; j
+1 < stmt
->children
.at(i
)->children
.size() && !found_match
; j
++)
2537 AstNode
*cond
= stmt
->children
.at(i
)->children
.at(j
)->clone();
2538 cond
->replace_variables(variables
, fcall
);
2540 cond
= new AstNode(AST_EQ
, expr
->clone(), cond
);
2541 while (cond
->simplify(true, false, false, 1, -1, false, true)) { }
2543 if (cond
->type
!= AST_CONSTANT
)
2544 log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n",
2545 stmt
->filename
.c_str(), stmt
->linenum
, fcall
->filename
.c_str(), fcall
->linenum
);
2547 found_match
= cond
->asBool();
2552 sel_case
= stmt
->children
.at(i
)->children
.back();
2557 block
->children
.erase(block
->children
.begin());
2559 block
->children
.insert(block
->children
.begin(), sel_case
->clone());
2565 if (stmt
->type
== AST_BLOCK
)
2567 block
->children
.erase(block
->children
.begin());
2568 block
->children
.insert(block
->children
.begin(), stmt
->children
.begin(), stmt
->children
.end());
2569 stmt
->children
.clear();
2574 log_error("Unsupported language construct in constant function at %s:%d (called from %s:%d).\n",
2575 stmt
->filename
.c_str(), stmt
->linenum
, fcall
->filename
.c_str(), fcall
->linenum
);
2579 if (delete_temp_block
)
2582 for (auto &it
: backup_scope
)
2583 if (it
.second
== NULL
)
2584 current_scope
.erase(it
.first
);
2586 current_scope
[it
.first
] = it
.second
;
2588 return AstNode::mkconst_bits(variables
.at(str
).val
.bits
, variables
.at(str
).is_signed
);