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"
38 using namespace AST_INTERNAL
;
40 // convert the AST into a simpler AST that has all parameters subsitited by their
41 // values, unrolled for-loops, expanded generate blocks, etc. when this function
42 // is done with an AST it can be converted into RTLIL using genRTLIL().
44 // this function also does all name resolving and sets the id2ast member of all
45 // nodes that link to a different node using names and lexical scoping.
46 bool AstNode::simplify(bool const_fold
, bool at_zero
, bool in_lvalue
, int stage
, int width_hint
, bool sign_hint
)
48 AstNode
*newNode
= NULL
;
49 bool did_something
= false;
53 assert(type
== AST_MODULE
);
55 while (simplify(const_fold
, at_zero
, in_lvalue
, 1, width_hint
, sign_hint
)) { }
57 if (!flag_nomem2reg
&& !get_bool_attribute("\\nomem2reg"))
59 std::map
<AstNode
*, std::set
<std::string
>> mem2reg_places
;
60 std::map
<AstNode
*, uint32_t> mem2reg_candidates
, dummy_proc_flags
;
61 uint32_t flags
= flag_mem2reg
? AstNode::MEM2REG_FL_ALL
: 0;
62 mem2reg_as_needed_pass1(mem2reg_places
, mem2reg_candidates
, dummy_proc_flags
, flags
);
64 std::set
<AstNode
*> mem2reg_set
;
65 for (auto &it
: mem2reg_candidates
)
67 AstNode
*mem
= it
.first
;
68 uint32_t memflags
= it
.second
;
69 assert((memflags
& ~0x00ffff00) == 0);
71 if (mem
->get_bool_attribute("\\nomem2reg"))
74 if (memflags
& AstNode::MEM2REG_FL_FORCED
)
77 if (memflags
& AstNode::MEM2REG_FL_EQ2
)
78 goto verbose_activate
;
80 if (memflags
& AstNode::MEM2REG_FL_SET_ASYNC
)
81 goto verbose_activate
;
83 if ((memflags
& AstNode::MEM2REG_FL_SET_INIT
) && (memflags
& AstNode::MEM2REG_FL_SET_ELSE
))
84 goto verbose_activate
;
86 // log("Note: Not replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
90 if (mem2reg_set
.count(mem
) == 0) {
91 log("Warning: Replacing memory %s with list of registers.", mem
->str
.c_str());
92 bool first_element
= true;
93 for (auto &place
: mem2reg_places
[it
.first
]) {
94 log("%s%s", first_element
? " See " : ", ", place
.c_str());
95 first_element
= false;
101 // log("Note: Replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
102 mem2reg_set
.insert(mem
);
105 for (auto node
: mem2reg_set
)
107 int mem_width
, mem_size
, addr_bits
;
108 node
->meminfo(mem_width
, mem_size
, addr_bits
);
110 for (int i
= 0; i
< mem_size
; i
++) {
111 AstNode
*reg
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
,
112 mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
113 reg
->str
= stringf("%s[%d]", node
->str
.c_str(), i
);
115 reg
->is_signed
= node
->is_signed
;
116 children
.push_back(reg
);
117 while (reg
->simplify(true, false, false, 1, -1, false)) { }
121 mem2reg_as_needed_pass2(mem2reg_set
, this, NULL
);
123 for (size_t i
= 0; i
< children
.size(); i
++) {
124 if (mem2reg_set
.count(children
[i
]) > 0) {
126 children
.erase(children
.begin() + (i
--));
131 while (simplify(const_fold
, at_zero
, in_lvalue
, 2, width_hint
, sign_hint
)) { }
135 current_filename
= filename
;
136 set_line_num(linenum
);
138 // we do not look inside a task or function
139 // (but as soon as a task of function is instanciated we process the generated AST as usual)
140 if (type
== AST_FUNCTION
|| type
== AST_TASK
)
143 // deactivate all calls non-synthesis system taks
144 if ((type
== AST_FCALL
|| type
== AST_TCALL
) && (str
== "$display" || str
== "$stop" || str
== "$finish")) {
149 // activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
150 if (type
== AST_WIRE
|| type
== AST_PARAMETER
|| type
== AST_LOCALPARAM
|| type
== AST_DEFPARAM
|| type
== AST_PARASET
|| type
== AST_RANGE
|| type
== AST_PREFIX
)
152 if (type
== AST_IDENTIFIER
&& current_scope
.count(str
) > 0 && (current_scope
[str
]->type
== AST_PARAMETER
|| current_scope
[str
]->type
== AST_LOCALPARAM
))
155 std::map
<std::string
, AstNode
*> backup_scope
;
157 // create name resolution entries for all objects with names
158 // also merge multiple declarations for the same wire (e.g. "output foobar; reg foobar;")
159 if (type
== AST_MODULE
) {
160 current_scope
.clear();
161 std::map
<std::string
, AstNode
*> this_wire_scope
;
162 for (size_t i
= 0; i
< children
.size(); i
++) {
163 AstNode
*node
= children
[i
];
164 if (node
->type
== AST_WIRE
) {
165 if (this_wire_scope
.count(node
->str
) > 0) {
166 AstNode
*first_node
= this_wire_scope
[node
->str
];
167 if (!node
->is_input
&& !node
->is_output
&& node
->is_reg
&& node
->children
.size() == 0)
168 goto wires_are_compatible
;
169 if (first_node
->children
.size() != node
->children
.size())
170 goto wires_are_incompatible
;
171 for (size_t j
= 0; j
< node
->children
.size(); j
++) {
172 AstNode
*n1
= first_node
->children
[j
], *n2
= node
->children
[j
];
173 if (n1
->type
== AST_RANGE
&& n2
->type
== AST_RANGE
&& n1
->range_valid
&& n2
->range_valid
) {
174 if (n1
->range_left
!= n2
->range_left
)
175 goto wires_are_incompatible
;
176 if (n1
->range_right
!= n2
->range_right
)
177 goto wires_are_incompatible
;
178 } else if (*n1
!= *n2
)
179 goto wires_are_incompatible
;
181 if (first_node
->range_left
!= node
->range_left
)
182 goto wires_are_incompatible
;
183 if (first_node
->range_right
!= node
->range_right
)
184 goto wires_are_incompatible
;
185 if (first_node
->port_id
== 0 && (node
->is_input
|| node
->is_output
))
186 goto wires_are_incompatible
;
187 wires_are_compatible
:
189 first_node
->is_input
= true;
191 first_node
->is_output
= true;
193 first_node
->is_reg
= true;
195 first_node
->is_signed
= true;
196 for (auto &it
: node
->attributes
) {
197 if (first_node
->attributes
.count(it
.first
) > 0)
198 delete first_node
->attributes
[it
.first
];
199 first_node
->attributes
[it
.first
] = it
.second
->clone();
201 children
.erase(children
.begin()+(i
--));
202 did_something
= true;
206 this_wire_scope
[node
->str
] = node
;
208 wires_are_incompatible
:
209 if (node
->type
== AST_PARAMETER
|| node
->type
== AST_LOCALPARAM
|| node
->type
== AST_WIRE
|| node
->type
== AST_AUTOWIRE
|| node
->type
== AST_GENVAR
||
210 node
->type
== AST_MEMORY
|| node
->type
== AST_FUNCTION
|| node
->type
== AST_TASK
|| node
->type
== AST_CELL
) {
211 backup_scope
[node
->str
] = current_scope
[node
->str
];
212 current_scope
[node
->str
] = node
;
215 for (size_t i
= 0; i
< children
.size(); i
++) {
216 AstNode
*node
= children
[i
];
217 if (node
->type
== AST_PARAMETER
|| node
->type
== AST_LOCALPARAM
|| node
->type
== AST_WIRE
|| node
->type
== AST_AUTOWIRE
)
218 while (node
->simplify(true, false, false, 1, -1, false)) { }
222 auto backup_current_block
= current_block
;
223 auto backup_current_block_child
= current_block_child
;
224 auto backup_current_top_block
= current_top_block
;
226 int backup_width_hint
= width_hint
;
227 bool backup_sign_hint
= sign_hint
;
229 bool detect_width_simple
= false;
230 bool child_0_is_self_determined
= false;
231 bool child_1_is_self_determined
= false;
232 bool children_are_self_determined
= false;
233 bool reset_width_after_children
= false;
240 while (children
[0]->simplify(false, false, true, stage
, -1, false) == true) { }
241 while (children
[1]->simplify(false, false, false, stage
, -1, false) == true) { }
242 children
[0]->detectSignWidth(backup_width_hint
, backup_sign_hint
);
243 children
[1]->detectSignWidth(width_hint
, sign_hint
);
244 width_hint
= std::max(width_hint
, backup_width_hint
);
245 child_0_is_self_determined
= true;
250 while (children
[0]->simplify(false, false, false, stage
, -1, false) == true) { }
251 children
[0]->detectSignWidth(width_hint
, sign_hint
);
252 if (children
.size() > 1) {
253 assert(children
[1]->type
== AST_RANGE
);
254 while (children
[1]->simplify(false, false, false, stage
, -1, false) == true) { }
255 if (!children
[1]->range_valid
)
256 log_error("Non-constant width range on parameter decl at %s:%d.\n", filename
.c_str(), linenum
);
257 width_hint
= std::max(width_hint
, children
[1]->range_left
- children
[1]->range_right
+ 1);
262 case AST_TO_UNSIGNED
:
268 case AST_REDUCE_XNOR
:
269 case AST_REDUCE_BOOL
:
270 detect_width_simple
= true;
271 children_are_self_determined
= true;
286 detect_width_simple
= true;
290 case AST_SHIFT_RIGHT
:
291 case AST_SHIFT_SLEFT
:
292 case AST_SHIFT_SRIGHT
:
294 detect_width_simple
= true;
295 child_1_is_self_determined
= true;
308 for (auto child
: children
) {
309 while (child
->simplify(false, false, in_lvalue
, stage
, -1, false) == true) { }
310 child
->detectSignWidthWorker(width_hint
, sign_hint
);
312 reset_width_after_children
= true;
318 detect_width_simple
= true;
319 children_are_self_determined
= true;
323 detect_width_simple
= true;
324 child_0_is_self_determined
= true;
328 detect_width_simple
= true;
329 children_are_self_determined
= true;
337 if (detect_width_simple
&& width_hint
< 0) {
338 for (auto child
: children
)
339 while (child
->simplify(false, false, in_lvalue
, stage
, -1, false) == true) { }
340 if (type
== AST_REPLICATE
)
341 while (children
[0]->simplify(true, false, in_lvalue
, stage
, -1, false) == true) { }
342 detectSignWidth(width_hint
, sign_hint
);
345 // simplify all children first
346 // (iterate by index as e.g. auto wires can add new children in the process)
347 for (size_t i
= 0; i
< children
.size(); i
++) {
348 bool did_something_here
= true;
349 if ((type
== AST_GENFOR
|| type
== AST_FOR
) && i
>= 3)
351 if ((type
== AST_GENIF
|| type
== AST_GENCASE
) && i
>= 1)
353 if (type
== AST_GENBLOCK
)
355 if (type
== AST_BLOCK
&& !str
.empty())
357 if (type
== AST_PREFIX
&& i
>= 1)
359 while (did_something_here
&& i
< children
.size()) {
360 bool const_fold_here
= const_fold
, in_lvalue_here
= in_lvalue
;
361 int width_hint_here
= width_hint
;
362 bool sign_hint_here
= sign_hint
;
363 if (i
== 0 && type
== AST_REPLICATE
)
364 const_fold_here
= true;
365 if (type
== AST_PARAMETER
|| type
== AST_LOCALPARAM
)
366 const_fold_here
= true;
367 if (i
== 0 && (type
== AST_ASSIGN
|| type
== AST_ASSIGN_EQ
|| type
== AST_ASSIGN_LE
))
368 in_lvalue_here
= true;
369 if (type
== AST_BLOCK
) {
370 current_block
= this;
371 current_block_child
= children
[i
];
373 if ((type
== AST_ALWAYS
|| type
== AST_INITIAL
) && children
[i
]->type
== AST_BLOCK
)
374 current_top_block
= children
[i
];
375 if (i
== 0 && child_0_is_self_determined
)
376 width_hint_here
= -1, sign_hint_here
= false;
377 if (i
== 1 && child_1_is_self_determined
)
378 width_hint_here
= -1, sign_hint_here
= false;
379 if (children_are_self_determined
)
380 width_hint_here
= -1, sign_hint_here
= false;
381 did_something_here
= children
[i
]->simplify(const_fold_here
, at_zero
, in_lvalue_here
, stage
, width_hint_here
, sign_hint_here
);
382 if (did_something_here
)
383 did_something
= true;
386 for (auto &attr
: attributes
) {
387 while (attr
.second
->simplify(true, false, false, stage
, -1, false)) { }
390 if (reset_width_after_children
) {
391 width_hint
= backup_width_hint
;
392 sign_hint
= backup_sign_hint
;
394 detectSignWidth(width_hint
, sign_hint
);
397 current_block
= backup_current_block
;
398 current_block_child
= backup_current_block_child
;
399 current_top_block
= backup_current_top_block
;
401 for (auto it
= backup_scope
.begin(); it
!= backup_scope
.end(); it
++) {
402 if (it
->second
== NULL
)
403 current_scope
.erase(it
->first
);
405 current_scope
[it
->first
] = it
->second
;
408 current_filename
= filename
;
409 set_line_num(linenum
);
411 if (type
== AST_MODULE
)
412 current_scope
.clear();
414 // convert defparam nodes to cell parameters
415 if (type
== AST_DEFPARAM
&& !str
.empty()) {
416 size_t pos
= str
.rfind('.');
417 if (pos
== std::string::npos
)
418 log_error("Defparam `%s' does not contain a dot (module/parameter seperator) at %s:%d!\n",
419 RTLIL::id2cstr(str
.c_str()), filename
.c_str(), linenum
);
420 std::string modname
= str
.substr(0, pos
), paraname
= "\\" + str
.substr(pos
+1);
421 if (current_scope
.count(modname
) == 0 || current_scope
.at(modname
)->type
!= AST_CELL
)
422 log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::id2cstr(modname
), RTLIL::id2cstr(paraname
), filename
.c_str(), linenum
);
423 AstNode
*cell
= current_scope
.at(modname
), *paraset
= clone();
424 cell
->children
.insert(cell
->children
.begin() + 1, paraset
);
425 paraset
->type
= AST_PARASET
;
426 paraset
->str
= paraname
;
430 // resolve constant prefixes
431 if (type
== AST_PREFIX
) {
432 if (children
[0]->type
!= AST_CONSTANT
) {
433 // dumpAst(NULL, "> ");
434 log_error("Index in generate block prefix syntax at %s:%d is not constant!\n", filename
.c_str(), linenum
);
436 assert(children
[1]->type
== AST_IDENTIFIER
);
437 newNode
= children
[1]->clone();
438 const char *second_part
= children
[1]->str
.c_str();
439 if (second_part
[0] == '\\')
441 newNode
->str
= stringf("%s[%d].%s", str
.c_str(), children
[0]->integer
, second_part
);
445 // annotate constant ranges
446 if (type
== AST_RANGE
) {
447 bool old_range_valid
= range_valid
;
451 assert(children
.size() >= 1);
452 if (children
[0]->type
== AST_CONSTANT
) {
454 range_left
= children
[0]->integer
;
455 if (children
.size() == 1)
456 range_right
= range_left
;
458 if (children
.size() >= 2) {
459 if (children
[1]->type
== AST_CONSTANT
)
460 range_right
= children
[1]->integer
;
464 if (old_range_valid
!= range_valid
)
465 did_something
= true;
466 if (range_valid
&& range_left
>= 0 && range_right
> range_left
) {
467 int tmp
= range_right
;
468 range_right
= range_left
;
473 // annotate wires with their ranges
474 if (type
== AST_WIRE
) {
475 if (children
.size() > 0) {
476 if (children
[0]->range_valid
) {
478 did_something
= true;
480 range_left
= children
[0]->range_left
;
481 range_right
= children
[0]->range_right
;
485 did_something
= true;
492 // trim/extend parameters
493 if ((type
== AST_PARAMETER
|| type
== AST_LOCALPARAM
) && children
[0]->type
== AST_CONSTANT
&& children
.size() > 1) {
494 if (!children
[1]->range_valid
)
495 log_error("Non-constant width range on parameter decl at %s:%d.\n", filename
.c_str(), linenum
);
496 int width
= children
[1]->range_left
- children
[1]->range_right
+ 1;
497 if (width
!= int(children
[0]->bits
.size())) {
498 RTLIL::SigSpec
sig(children
[0]->bits
);
499 sig
.extend_u0(width
, children
[0]->is_signed
);
500 AstNode
*old_child_0
= children
[0];
501 children
[0] = mkconst_bits(sig
.as_const().bits
, children
[0]->is_signed
);
504 children
[0]->is_signed
= is_signed
;
507 // annotate identifiers using scope resolution and create auto-wires as needed
508 if (type
== AST_IDENTIFIER
) {
509 if (current_scope
.count(str
) == 0) {
510 for (auto node
: current_ast_mod
->children
) {
511 if ((node
->type
== AST_PARAMETER
|| node
->type
== AST_LOCALPARAM
|| node
->type
== AST_WIRE
|| node
->type
== AST_AUTOWIRE
|| node
->type
== AST_GENVAR
||
512 node
->type
== AST_MEMORY
|| node
->type
== AST_FUNCTION
|| node
->type
== AST_TASK
) && str
== node
->str
) {
513 current_scope
[node
->str
] = node
;
518 if (current_scope
.count(str
) == 0) {
519 // log("Warning: Creating auto-wire `%s' in module `%s'.\n", str.c_str(), current_ast_mod->str.c_str());
520 AstNode
*auto_wire
= new AstNode(AST_AUTOWIRE
);
521 auto_wire
->str
= str
;
522 current_ast_mod
->children
.push_back(auto_wire
);
523 current_scope
[str
] = auto_wire
;
524 did_something
= true;
526 id2ast
= current_scope
[str
];
529 // split memory access with bit select to individual statements
530 if (type
== AST_IDENTIFIER
&& children
.size() == 2 && children
[0]->type
== AST_RANGE
&& children
[1]->type
== AST_RANGE
)
532 if (id2ast
== NULL
|| id2ast
->type
!= AST_MEMORY
|| children
[0]->children
.size() != 1 || in_lvalue
)
533 log_error("Invalid bit-select on memory access at %s:%d!\n", filename
.c_str(), linenum
);
535 int mem_width
, mem_size
, addr_bits
;
536 id2ast
->meminfo(mem_width
, mem_size
, addr_bits
);
538 std::stringstream sstr
;
539 sstr
<< "$mem2bits$" << children
[0]->str
<< "$" << filename
<< ":" << linenum
<< "$" << (RTLIL::autoidx
++);
540 std::string wire_id
= sstr
.str();
542 AstNode
*wire
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
545 wire
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
546 current_ast_mod
->children
.push_back(wire
);
547 while (wire
->simplify(true, false, false, 1, -1, false)) { }
549 AstNode
*data
= clone();
550 delete data
->children
[1];
551 data
->children
.pop_back();
553 AstNode
*assign
= new AstNode(AST_ASSIGN_EQ
, new AstNode(AST_IDENTIFIER
), data
);
554 assign
->children
[0]->str
= wire_id
;
558 size_t assign_idx
= 0;
559 while (assign_idx
< current_block
->children
.size() && current_block
->children
[assign_idx
] != current_block_child
)
561 log_assert(assign_idx
< current_block
->children
.size());
562 current_block
->children
.insert(current_block
->children
.begin()+assign_idx
, assign
);
567 AstNode
*proc
= new AstNode(AST_ALWAYS
, new AstNode(AST_BLOCK
));
568 proc
->children
[0]->children
.push_back(assign
);
569 current_ast_mod
->children
.push_back(proc
);
572 newNode
= new AstNode(AST_IDENTIFIER
, children
[1]->clone());
573 newNode
->str
= wire_id
;
574 newNode
->id2ast
= wire
;
578 // unroll for loops and generate-for blocks
579 if ((type
== AST_GENFOR
|| type
== AST_FOR
) && children
.size() != 0)
581 AstNode
*init_ast
= children
[0];
582 AstNode
*while_ast
= children
[1];
583 AstNode
*next_ast
= children
[2];
584 AstNode
*body_ast
= children
[3];
586 while (body_ast
->type
== AST_GENBLOCK
&& body_ast
->str
.empty() &&
587 body_ast
->children
.size() == 1 && body_ast
->children
.at(0)->type
== AST_GENBLOCK
)
588 body_ast
= body_ast
->children
.at(0);
590 if (init_ast
->type
!= AST_ASSIGN_EQ
)
591 log_error("Unsupported 1st expression of generate for-loop at %s:%d!\n", filename
.c_str(), linenum
);
592 if (next_ast
->type
!= AST_ASSIGN_EQ
)
593 log_error("Unsupported 3rd expression of generate for-loop at %s:%d!\n", filename
.c_str(), linenum
);
595 if (type
== AST_GENFOR
) {
596 if (init_ast
->children
[0]->id2ast
== NULL
|| init_ast
->children
[0]->id2ast
->type
!= AST_GENVAR
)
597 log_error("Left hand side of 1st expression of generate for-loop at %s:%d is not a gen var!\n", filename
.c_str(), linenum
);
598 if (next_ast
->children
[0]->id2ast
== NULL
|| next_ast
->children
[0]->id2ast
->type
!= AST_GENVAR
)
599 log_error("Left hand side of 3rd expression of generate for-loop at %s:%d is not a gen var!\n", filename
.c_str(), linenum
);
601 if (init_ast
->children
[0]->id2ast
== NULL
|| init_ast
->children
[0]->id2ast
->type
!= AST_WIRE
)
602 log_error("Left hand side of 1st expression of generate for-loop at %s:%d is not a register!\n", filename
.c_str(), linenum
);
603 if (next_ast
->children
[0]->id2ast
== NULL
|| next_ast
->children
[0]->id2ast
->type
!= AST_WIRE
)
604 log_error("Left hand side of 3rd expression of generate for-loop at %s:%d is not a register!\n", filename
.c_str(), linenum
);
607 if (init_ast
->children
[0]->id2ast
!= next_ast
->children
[0]->id2ast
)
608 log_error("Incompatible left-hand sides in 1st and 3rd expression of generate for-loop at %s:%d!\n", filename
.c_str(), linenum
);
610 // eval 1st expression
611 AstNode
*varbuf
= init_ast
->children
[1]->clone();
612 while (varbuf
->simplify(true, false, false, stage
, width_hint
, sign_hint
)) { }
614 if (varbuf
->type
!= AST_CONSTANT
)
615 log_error("Right hand side of 1st expression of generate for-loop at %s:%d is not constant!\n", filename
.c_str(), linenum
);
617 varbuf
= new AstNode(AST_LOCALPARAM
, varbuf
);
618 varbuf
->str
= init_ast
->children
[0]->str
;
620 AstNode
*backup_scope_varbuf
= current_scope
[varbuf
->str
];
621 current_scope
[varbuf
->str
] = varbuf
;
623 size_t current_block_idx
= 0;
624 if (type
== AST_FOR
) {
625 while (current_block_idx
< current_block
->children
.size() &&
626 current_block
->children
[current_block_idx
] != current_block_child
)
632 // eval 2nd expression
633 AstNode
*buf
= while_ast
->clone();
634 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
)) { }
636 if (buf
->type
!= AST_CONSTANT
)
637 log_error("2nd expression of generate for-loop at %s:%d is not constant!\n", filename
.c_str(), linenum
);
639 if (buf
->integer
== 0) {
646 int index
= varbuf
->children
[0]->integer
;
647 if (body_ast
->type
== AST_GENBLOCK
)
648 buf
= body_ast
->clone();
650 buf
= new AstNode(AST_GENBLOCK
, body_ast
->clone());
651 if (buf
->str
.empty()) {
652 std::stringstream sstr
;
653 sstr
<< "$genblock$" << filename
<< ":" << linenum
<< "$" << (RTLIL::autoidx
++);
654 buf
->str
= sstr
.str();
656 std::map
<std::string
, std::string
> name_map
;
657 std::stringstream sstr
;
658 sstr
<< buf
->str
<< "[" << index
<< "].";
659 buf
->expand_genblock(varbuf
->str
, sstr
.str(), name_map
);
661 if (type
== AST_GENFOR
) {
662 for (size_t i
= 0; i
< buf
->children
.size(); i
++) {
663 buf
->children
[i
]->simplify(false, false, false, stage
, -1, false);
664 current_ast_mod
->children
.push_back(buf
->children
[i
]);
667 for (size_t i
= 0; i
< buf
->children
.size(); i
++)
668 current_block
->children
.insert(current_block
->children
.begin() + current_block_idx
++, buf
->children
[i
]);
670 buf
->children
.clear();
673 // eval 3rd expression
674 buf
= next_ast
->children
[1]->clone();
675 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
)) { }
677 if (buf
->type
!= AST_CONSTANT
)
678 log_error("Right hand side of 3rd expression of generate for-loop at %s:%d is not constant!\n", filename
.c_str(), linenum
);
680 delete varbuf
->children
[0];
681 varbuf
->children
[0] = buf
;
684 current_scope
[varbuf
->str
] = backup_scope_varbuf
;
687 did_something
= true;
690 // transform block with name
691 if (type
== AST_BLOCK
&& !str
.empty())
693 std::map
<std::string
, std::string
> name_map
;
694 expand_genblock(std::string(), str
+ ".", name_map
);
696 std::vector
<AstNode
*> new_children
;
697 for (size_t i
= 0; i
< children
.size(); i
++)
698 if (children
[i
]->type
== AST_WIRE
) {
699 children
[i
]->simplify(false, false, false, stage
, -1, false);
700 current_ast_mod
->children
.push_back(children
[i
]);
702 new_children
.push_back(children
[i
]);
704 children
.swap(new_children
);
705 did_something
= true;
709 // simplify unconditional generate block
710 if (type
== AST_GENBLOCK
&& children
.size() != 0)
713 std::map
<std::string
, std::string
> name_map
;
714 expand_genblock(std::string(), str
+ ".", name_map
);
717 for (size_t i
= 0; i
< children
.size(); i
++) {
718 children
[i
]->simplify(false, false, false, stage
, -1, false);
719 current_ast_mod
->children
.push_back(children
[i
]);
723 did_something
= true;
726 // simplify generate-if blocks
727 if (type
== AST_GENIF
&& children
.size() != 0)
729 AstNode
*buf
= children
[0]->clone();
730 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
)) { }
731 if (buf
->type
!= AST_CONSTANT
) {
732 // for (auto f : log_files)
733 // dumpAst(f, "verilog-ast> ");
734 log_error("Condition for generate if at %s:%d is not constant!\n", filename
.c_str(), linenum
);
736 if (buf
->asBool() != 0) {
738 buf
= children
[1]->clone();
741 buf
= children
.size() > 2 ? children
[2]->clone() : NULL
;
746 if (buf
->type
!= AST_GENBLOCK
)
747 buf
= new AstNode(AST_GENBLOCK
, buf
);
749 if (!buf
->str
.empty()) {
750 std::map
<std::string
, std::string
> name_map
;
751 buf
->expand_genblock(std::string(), buf
->str
+ ".", name_map
);
754 for (size_t i
= 0; i
< buf
->children
.size(); i
++) {
755 buf
->children
[i
]->simplify(false, false, false, stage
, -1, false);
756 current_ast_mod
->children
.push_back(buf
->children
[i
]);
759 buf
->children
.clear();
764 did_something
= true;
767 // simplify generate-case blocks
768 if (type
== AST_GENCASE
&& children
.size() != 0)
770 AstNode
*buf
= children
[0]->clone();
771 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
)) { }
772 if (buf
->type
!= AST_CONSTANT
) {
773 // for (auto f : log_files)
774 // dumpAst(f, "verilog-ast> ");
775 log_error("Condition for generate case at %s:%d is not constant!\n", filename
.c_str(), linenum
);
778 bool ref_signed
= buf
->is_signed
;
779 RTLIL::Const ref_value
= buf
->bitsAsConst();
782 AstNode
*selected_case
= NULL
;
783 for (size_t i
= 1; i
< children
.size(); i
++)
785 log_assert(children
.at(i
)->type
== AST_COND
);
787 AstNode
*this_genblock
= NULL
;
788 for (auto child
: children
.at(i
)->children
) {
789 log_assert(this_genblock
== NULL
);
790 if (child
->type
== AST_GENBLOCK
)
791 this_genblock
= child
;
794 for (auto child
: children
.at(i
)->children
)
796 if (child
->type
== AST_DEFAULT
) {
797 if (selected_case
== NULL
)
798 selected_case
= this_genblock
;
801 if (child
->type
== AST_GENBLOCK
)
804 buf
= child
->clone();
805 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
)) { }
806 if (buf
->type
!= AST_CONSTANT
) {
807 // for (auto f : log_files)
808 // dumpAst(f, "verilog-ast> ");
809 log_error("Expression in generate case at %s:%d is not constant!\n", filename
.c_str(), linenum
);
812 if (RTLIL::const_eq(ref_value
, buf
->bitsAsConst(), ref_signed
&& buf
->is_signed
, ref_signed
&& buf
->is_signed
, 1).as_bool()) {
813 selected_case
= this_genblock
;
820 if (selected_case
!= NULL
)
822 log_assert(selected_case
->type
== AST_GENBLOCK
);
823 buf
= selected_case
->clone();
825 if (!buf
->str
.empty()) {
826 std::map
<std::string
, std::string
> name_map
;
827 buf
->expand_genblock(std::string(), buf
->str
+ ".", name_map
);
830 for (size_t i
= 0; i
< buf
->children
.size(); i
++) {
831 buf
->children
[i
]->simplify(false, false, false, stage
, -1, false);
832 current_ast_mod
->children
.push_back(buf
->children
[i
]);
835 buf
->children
.clear();
840 did_something
= true;
843 // replace primitives with assignmens
844 if (type
== AST_PRIMITIVE
)
846 if (children
.size() < 2)
847 log_error("Insufficient number of arguments for primitive `%s' at %s:%d!\n",
848 str
.c_str(), filename
.c_str(), linenum
);
850 std::vector
<AstNode
*> children_list
;
851 for (auto child
: children
) {
852 assert(child
->type
== AST_ARGUMENT
);
853 assert(child
->children
.size() == 1);
854 children_list
.push_back(child
->children
[0]);
855 child
->children
.clear();
860 if (str
== "bufif0" || str
== "bufif1" || str
== "notif0" || str
== "notif1")
862 if (children_list
.size() != 3)
863 log_error("Invalid number of arguments for primitive `%s' at %s:%d!\n",
864 str
.c_str(), filename
.c_str(), linenum
);
866 std::vector
<RTLIL::State
> z_const(1, RTLIL::State::Sz
);
868 AstNode
*mux_input
= children_list
.at(1);
869 if (str
== "notif0" || str
== "notif1") {
870 mux_input
= new AstNode(AST_BIT_NOT
, mux_input
);
872 AstNode
*node
= new AstNode(AST_TERNARY
, children_list
.at(2));
873 if (str
== "bufif0") {
874 node
->children
.push_back(AstNode::mkconst_bits(z_const
, false));
875 node
->children
.push_back(mux_input
);
877 node
->children
.push_back(mux_input
);
878 node
->children
.push_back(AstNode::mkconst_bits(z_const
, false));
883 children
.push_back(children_list
.at(0));
884 children
.push_back(node
);
885 did_something
= true;
889 AstNodeType op_type
= AST_NONE
;
890 bool invert_results
= false;
893 op_type
= AST_BIT_AND
;
895 op_type
= AST_BIT_AND
, invert_results
= true;
897 op_type
= AST_BIT_OR
;
899 op_type
= AST_BIT_OR
, invert_results
= true;
901 op_type
= AST_BIT_XOR
;
903 op_type
= AST_BIT_XOR
, invert_results
= true;
907 op_type
= AST_POS
, invert_results
= true;
908 assert(op_type
!= AST_NONE
);
910 AstNode
*node
= children_list
[1];
911 if (op_type
!= AST_POS
)
912 for (size_t i
= 2; i
< children_list
.size(); i
++)
913 node
= new AstNode(op_type
, node
, children_list
[i
]);
915 node
= new AstNode(AST_BIT_NOT
, node
);
919 children
.push_back(children_list
[0]);
920 children
.push_back(node
);
921 did_something
= true;
925 // replace dynamic ranges in left-hand side expressions (e.g. "foo[bar] <= 1'b1;") with
926 // a big case block that selects the correct single-bit assignment.
927 if (type
== AST_ASSIGN_EQ
|| type
== AST_ASSIGN_LE
) {
928 if (children
[0]->type
!= AST_IDENTIFIER
|| children
[0]->children
.size() == 0)
929 goto skip_dynamic_range_lvalue_expansion
;
930 if (children
[0]->children
[0]->range_valid
|| did_something
)
931 goto skip_dynamic_range_lvalue_expansion
;
932 if (children
[0]->id2ast
== NULL
|| children
[0]->id2ast
->type
!= AST_WIRE
)
933 goto skip_dynamic_range_lvalue_expansion
;
934 if (!children
[0]->id2ast
->range_valid
)
935 goto skip_dynamic_range_lvalue_expansion
;
936 int source_width
= children
[0]->id2ast
->range_left
- children
[0]->id2ast
->range_right
+ 1;
937 int result_width
= 1;
938 AstNode
*shift_expr
= NULL
;
939 AstNode
*range
= children
[0]->children
[0];
940 if (range
->children
.size() == 1) {
941 shift_expr
= range
->children
[0]->clone();
943 shift_expr
= range
->children
[1]->clone();
944 AstNode
*left_at_zero_ast
= range
->children
[0]->clone();
945 AstNode
*right_at_zero_ast
= range
->children
[1]->clone();
946 while (left_at_zero_ast
->simplify(true, true, false, stage
, -1, false)) { }
947 while (right_at_zero_ast
->simplify(true, true, false, stage
, -1, false)) { }
948 if (left_at_zero_ast
->type
!= AST_CONSTANT
|| right_at_zero_ast
->type
!= AST_CONSTANT
)
949 log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n",
950 str
.c_str(), filename
.c_str(), linenum
);
951 result_width
= left_at_zero_ast
->integer
- right_at_zero_ast
->integer
+ 1;
953 did_something
= true;
954 newNode
= new AstNode(AST_CASE
, shift_expr
);
955 for (int i
= 0; i
<= source_width
-result_width
; i
++) {
956 int start_bit
= children
[0]->id2ast
->range_right
+ i
;
957 AstNode
*cond
= new AstNode(AST_COND
, mkconst_int(start_bit
, true));
958 AstNode
*lvalue
= children
[0]->clone();
959 lvalue
->delete_children();
960 lvalue
->children
.push_back(new AstNode(AST_RANGE
,
961 mkconst_int(start_bit
+result_width
-1, true), mkconst_int(start_bit
, true)));
962 cond
->children
.push_back(new AstNode(AST_BLOCK
, new AstNode(type
, lvalue
, children
[1]->clone())));
963 newNode
->children
.push_back(cond
);
967 skip_dynamic_range_lvalue_expansion
:;
969 if (stage
> 1 && type
== AST_ASSERT
&& current_block
!= NULL
)
971 std::stringstream sstr
;
972 sstr
<< "$assert$" << filename
<< ":" << linenum
<< "$" << (RTLIL::autoidx
++);
973 std::string id_check
= sstr
.str() + "_CHECK", id_en
= sstr
.str() + "_EN";
975 AstNode
*wire_check
= new AstNode(AST_WIRE
);
976 wire_check
->str
= id_check
;
977 current_ast_mod
->children
.push_back(wire_check
);
978 current_scope
[wire_check
->str
] = wire_check
;
979 while (wire_check
->simplify(true, false, false, 1, -1, false)) { }
981 AstNode
*wire_en
= new AstNode(AST_WIRE
);
982 wire_en
->str
= id_en
;
983 current_ast_mod
->children
.push_back(wire_en
);
984 current_scope
[wire_en
->str
] = wire_en
;
985 while (wire_en
->simplify(true, false, false, 1, -1, false)) { }
987 std::vector
<RTLIL::State
> x_bit
;
988 x_bit
.push_back(RTLIL::State::Sx
);
990 AstNode
*assign_check
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_bits(x_bit
, false));
991 assign_check
->children
[0]->str
= id_check
;
993 AstNode
*assign_en
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_int(0, false, 1));
994 assign_en
->children
[0]->str
= id_en
;
996 AstNode
*default_signals
= new AstNode(AST_BLOCK
);
997 default_signals
->children
.push_back(assign_check
);
998 default_signals
->children
.push_back(assign_en
);
999 current_top_block
->children
.insert(current_top_block
->children
.begin(), default_signals
);
1001 assign_check
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), new AstNode(AST_REDUCE_BOOL
, children
[0]->clone()));
1002 assign_check
->children
[0]->str
= id_check
;
1004 assign_en
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_int(1, false, 1));
1005 assign_en
->children
[0]->str
= id_en
;
1007 newNode
= new AstNode(AST_BLOCK
);
1008 newNode
->children
.push_back(assign_check
);
1009 newNode
->children
.push_back(assign_en
);
1011 AstNode
*assertnode
= new AstNode(AST_ASSERT
);
1012 assertnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
1013 assertnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
1014 assertnode
->children
[0]->str
= id_check
;
1015 assertnode
->children
[1]->str
= id_en
;
1016 assertnode
->attributes
.swap(attributes
);
1017 current_ast_mod
->children
.push_back(assertnode
);
1022 if (stage
> 1 && type
== AST_ASSERT
&& children
.size() == 1)
1024 children
[0] = new AstNode(AST_REDUCE_BOOL
, children
[0]->clone());
1025 children
.push_back(mkconst_int(1, false, 1));
1026 did_something
= true;
1029 // found right-hand side identifier for memory -> replace with memory read port
1030 if (stage
> 1 && type
== AST_IDENTIFIER
&& id2ast
!= NULL
&& id2ast
->type
== AST_MEMORY
&& !in_lvalue
&&
1031 children
[0]->type
== AST_RANGE
&& children
[0]->children
.size() == 1) {
1032 newNode
= new AstNode(AST_MEMRD
, children
[0]->children
[0]->clone());
1034 newNode
->id2ast
= id2ast
;
1038 // assignment with memory in left-hand side expression -> replace with memory write port
1039 if (stage
> 1 && (type
== AST_ASSIGN_EQ
|| type
== AST_ASSIGN_LE
) && children
[0]->type
== AST_IDENTIFIER
&&
1040 children
[0]->children
.size() == 1 && children
[0]->id2ast
&& children
[0]->id2ast
->type
== AST_MEMORY
&&
1041 children
[0]->id2ast
->children
.size() >= 2 && children
[0]->id2ast
->children
[0]->range_valid
&&
1042 children
[0]->id2ast
->children
[1]->range_valid
)
1044 std::stringstream sstr
;
1045 sstr
<< "$memwr$" << children
[0]->str
<< "$" << filename
<< ":" << linenum
<< "$" << (RTLIL::autoidx
++);
1046 std::string id_addr
= sstr
.str() + "_ADDR", id_data
= sstr
.str() + "_DATA", id_en
= sstr
.str() + "_EN";
1048 if (type
== AST_ASSIGN_EQ
)
1049 log("Warining: Blocking assignment to memory in line %s:%d is handled like a non-blocking assignment.\n",
1050 filename
.c_str(), linenum
);
1052 int mem_width
, mem_size
, addr_bits
;
1053 children
[0]->id2ast
->meminfo(mem_width
, mem_size
, addr_bits
);
1055 AstNode
*wire_addr
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(addr_bits
-1, true), mkconst_int(0, true)));
1056 wire_addr
->str
= id_addr
;
1057 current_ast_mod
->children
.push_back(wire_addr
);
1058 current_scope
[wire_addr
->str
] = wire_addr
;
1059 while (wire_addr
->simplify(true, false, false, 1, -1, false)) { }
1061 AstNode
*wire_data
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
1062 wire_data
->str
= id_data
;
1063 current_ast_mod
->children
.push_back(wire_data
);
1064 current_scope
[wire_data
->str
] = wire_data
;
1065 while (wire_data
->simplify(true, false, false, 1, -1, false)) { }
1067 AstNode
*wire_en
= new AstNode(AST_WIRE
);
1068 wire_en
->str
= id_en
;
1069 current_ast_mod
->children
.push_back(wire_en
);
1070 current_scope
[wire_en
->str
] = wire_en
;
1071 while (wire_en
->simplify(true, false, false, 1, -1, false)) { }
1073 std::vector
<RTLIL::State
> x_bits
;
1074 for (int i
= 0; i
< mem_width
; i
++)
1075 x_bits
.push_back(RTLIL::State::Sx
);
1077 AstNode
*assign_addr
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_bits(x_bits
, false));
1078 assign_addr
->children
[0]->str
= id_addr
;
1080 AstNode
*assign_data
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_bits(x_bits
, false));
1081 assign_data
->children
[0]->str
= id_data
;
1083 AstNode
*assign_en
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_int(0, false, 1));
1084 assign_en
->children
[0]->str
= id_en
;
1086 AstNode
*default_signals
= new AstNode(AST_BLOCK
);
1087 default_signals
->children
.push_back(assign_addr
);
1088 default_signals
->children
.push_back(assign_data
);
1089 default_signals
->children
.push_back(assign_en
);
1090 current_top_block
->children
.insert(current_top_block
->children
.begin(), default_signals
);
1092 assign_addr
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), children
[0]->children
[0]->children
[0]->clone());
1093 assign_addr
->children
[0]->str
= id_addr
;
1095 assign_data
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), children
[1]->clone());
1096 assign_data
->children
[0]->str
= id_data
;
1098 assign_en
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_int(1, false, 1));
1099 assign_en
->children
[0]->str
= id_en
;
1101 newNode
= new AstNode(AST_BLOCK
);
1102 newNode
->children
.push_back(assign_addr
);
1103 newNode
->children
.push_back(assign_data
);
1104 newNode
->children
.push_back(assign_en
);
1106 AstNode
*wrnode
= new AstNode(AST_MEMWR
);
1107 wrnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
1108 wrnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
1109 wrnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
1110 wrnode
->str
= children
[0]->str
;
1111 wrnode
->children
[0]->str
= id_addr
;
1112 wrnode
->children
[1]->str
= id_data
;
1113 wrnode
->children
[2]->str
= id_en
;
1114 current_ast_mod
->children
.push_back(wrnode
);
1119 // replace function and task calls with the code from the function or task
1120 if ((type
== AST_FCALL
|| type
== AST_TCALL
) && !str
.empty())
1122 if (type
== AST_FCALL
)
1124 if (str
== "\\$clog2")
1126 AstNode
*buf
= children
[0]->clone();
1127 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
)) { }
1128 if (buf
->type
!= AST_CONSTANT
)
1129 log_error("Failed to evaluate system function `%s' with non-constant value at %s:%d.\n", str
.c_str(), filename
.c_str(), linenum
);
1131 RTLIL::Const arg_value
= buf
->bitsAsConst();
1132 uint32_t result
= 0;
1133 for (size_t i
= 0; i
< arg_value
.bits
.size(); i
++)
1134 if (arg_value
.bits
.at(i
) == RTLIL::State::S1
)
1137 newNode
= mkconst_int(result
, false);
1141 if (current_scope
.count(str
) == 0 || current_scope
[str
]->type
!= AST_FUNCTION
)
1142 log_error("Can't resolve function name `%s' at %s:%d.\n", str
.c_str(), filename
.c_str(), linenum
);
1144 if (type
== AST_TCALL
) {
1145 if (current_scope
.count(str
) == 0 || current_scope
[str
]->type
!= AST_TASK
)
1146 log_error("Can't resolve task name `%s' at %s:%d.\n", str
.c_str(), filename
.c_str(), linenum
);
1149 AstNode
*decl
= current_scope
[str
];
1150 std::stringstream sstr
;
1151 sstr
<< "$func$" << str
<< "$" << filename
<< ":" << linenum
<< "$" << (RTLIL::autoidx
++) << "$";
1152 std::string prefix
= sstr
.str();
1154 size_t arg_count
= 0;
1155 std::map
<std::string
, std::string
> replace_rules
;
1157 if (current_block
== NULL
)
1159 assert(type
== AST_FCALL
);
1161 AstNode
*wire
= NULL
;
1162 for (auto child
: decl
->children
)
1163 if (child
->type
== AST_WIRE
&& child
->str
== str
)
1164 wire
= child
->clone();
1165 assert(wire
!= NULL
);
1167 wire
->str
= prefix
+ str
;
1169 wire
->is_input
= false;
1170 wire
->is_output
= false;
1172 current_ast_mod
->children
.push_back(wire
);
1173 while (wire
->simplify(true, false, false, 1, -1, false)) { }
1175 AstNode
*lvalue
= new AstNode(AST_IDENTIFIER
);
1176 lvalue
->str
= wire
->str
;
1178 AstNode
*always
= new AstNode(AST_ALWAYS
, new AstNode(AST_BLOCK
,
1179 new AstNode(AST_ASSIGN_EQ
, lvalue
, clone())));
1180 current_ast_mod
->children
.push_back(always
);
1182 goto replace_fcall_with_id
;
1185 for (auto child
: decl
->children
)
1187 if (child
->type
== AST_WIRE
)
1189 AstNode
*wire
= child
->clone();
1190 wire
->str
= prefix
+ wire
->str
;
1192 wire
->is_input
= false;
1193 wire
->is_output
= false;
1194 current_ast_mod
->children
.push_back(wire
);
1195 while (wire
->simplify(true, false, false, 1, -1, false)) { }
1197 replace_rules
[child
->str
] = wire
->str
;
1199 if (child
->is_input
&& arg_count
< children
.size())
1201 AstNode
*arg
= children
[arg_count
++]->clone();
1202 AstNode
*wire_id
= new AstNode(AST_IDENTIFIER
);
1203 wire_id
->str
= wire
->str
;
1204 AstNode
*assign
= new AstNode(AST_ASSIGN_EQ
, wire_id
, arg
);
1206 for (auto it
= current_block
->children
.begin(); it
!= current_block
->children
.end(); it
++) {
1207 if (*it
!= current_block_child
)
1209 current_block
->children
.insert(it
, assign
);
1216 AstNode
*stmt
= child
->clone();
1217 stmt
->replace_ids(replace_rules
);
1219 for (auto it
= current_block
->children
.begin(); it
!= current_block
->children
.end(); it
++) {
1220 if (*it
!= current_block_child
)
1222 current_block
->children
.insert(it
, stmt
);
1228 replace_fcall_with_id
:
1229 if (type
== AST_FCALL
) {
1231 type
= AST_IDENTIFIER
;
1234 if (type
== AST_TCALL
)
1236 did_something
= true;
1239 // perform const folding when activated
1240 if (const_fold
&& newNode
== NULL
)
1243 std::vector
<RTLIL::State
> tmp_bits
;
1244 RTLIL::Const (*const_func
)(const RTLIL::Const
&, const RTLIL::Const
&, bool, bool, int);
1245 RTLIL::Const dummy_arg
;
1249 case AST_IDENTIFIER
:
1250 if (current_scope
.count(str
) > 0 && (current_scope
[str
]->type
== AST_PARAMETER
|| current_scope
[str
]->type
== AST_LOCALPARAM
)) {
1251 if (current_scope
[str
]->children
[0]->type
== AST_CONSTANT
) {
1252 if (children
.size() != 0 && children
[0]->type
== AST_RANGE
&& children
[0]->range_valid
) {
1253 std::vector
<RTLIL::State
> data
;
1254 for (int i
= children
[0]->range_right
; i
<= children
[0]->range_left
; i
++)
1255 data
.push_back(current_scope
[str
]->children
[0]->bits
[i
]);
1256 newNode
= mkconst_bits(data
, false);
1258 if (children
.size() == 0)
1259 newNode
= current_scope
[str
]->children
[0]->clone();
1262 else if (at_zero
&& current_scope
.count(str
) > 0 && (current_scope
[str
]->type
== AST_WIRE
|| current_scope
[str
]->type
== AST_AUTOWIRE
)) {
1263 newNode
= mkconst_int(0, sign_hint
, width_hint
);
1267 if (children
[0]->type
== AST_CONSTANT
) {
1268 RTLIL::Const y
= RTLIL::const_not(children
[0]->bitsAsConst(width_hint
, sign_hint
), dummy_arg
, sign_hint
, false, width_hint
);
1269 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1273 case AST_TO_UNSIGNED
:
1274 if (children
[0]->type
== AST_CONSTANT
) {
1275 RTLIL::Const y
= children
[0]->bitsAsConst(width_hint
, sign_hint
);
1276 newNode
= mkconst_bits(y
.bits
, type
== AST_TO_SIGNED
);
1279 if (0) { case AST_BIT_AND
: const_func
= RTLIL::const_and
; }
1280 if (0) { case AST_BIT_OR
: const_func
= RTLIL::const_or
; }
1281 if (0) { case AST_BIT_XOR
: const_func
= RTLIL::const_xor
; }
1282 if (0) { case AST_BIT_XNOR
: const_func
= RTLIL::const_xnor
; }
1283 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1284 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(width_hint
, sign_hint
),
1285 children
[1]->bitsAsConst(width_hint
, sign_hint
), sign_hint
, sign_hint
, width_hint
);
1286 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1289 if (0) { case AST_REDUCE_AND
: const_func
= RTLIL::const_reduce_and
; }
1290 if (0) { case AST_REDUCE_OR
: const_func
= RTLIL::const_reduce_or
; }
1291 if (0) { case AST_REDUCE_XOR
: const_func
= RTLIL::const_reduce_xor
; }
1292 if (0) { case AST_REDUCE_XNOR
: const_func
= RTLIL::const_reduce_xnor
; }
1293 if (0) { case AST_REDUCE_BOOL
: const_func
= RTLIL::const_reduce_bool
; }
1294 if (children
[0]->type
== AST_CONSTANT
) {
1295 RTLIL::Const y
= const_func(RTLIL::Const(children
[0]->bits
), dummy_arg
, false, false, -1);
1296 newNode
= mkconst_bits(y
.bits
, false);
1300 if (children
[0]->type
== AST_CONSTANT
) {
1301 RTLIL::Const y
= RTLIL::const_logic_not(RTLIL::Const(children
[0]->bits
), dummy_arg
, children
[0]->is_signed
, false, -1);
1302 newNode
= mkconst_bits(y
.bits
, false);
1305 if (0) { case AST_LOGIC_AND
: const_func
= RTLIL::const_logic_and
; }
1306 if (0) { case AST_LOGIC_OR
: const_func
= RTLIL::const_logic_or
; }
1307 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1308 RTLIL::Const y
= const_func(RTLIL::Const(children
[0]->bits
), RTLIL::Const(children
[1]->bits
),
1309 children
[0]->is_signed
, children
[1]->is_signed
, -1);
1310 newNode
= mkconst_bits(y
.bits
, false);
1313 if (0) { case AST_SHIFT_LEFT
: const_func
= RTLIL::const_shl
; }
1314 if (0) { case AST_SHIFT_RIGHT
: const_func
= RTLIL::const_shr
; }
1315 if (0) { case AST_SHIFT_SLEFT
: const_func
= RTLIL::const_sshl
; }
1316 if (0) { case AST_SHIFT_SRIGHT
: const_func
= RTLIL::const_sshr
; }
1317 if (0) { case AST_POW
: const_func
= RTLIL::const_pow
; }
1318 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1319 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(width_hint
, sign_hint
),
1320 RTLIL::Const(children
[1]->bits
), sign_hint
, type
== AST_POW
? children
[1]->is_signed
: false, width_hint
);
1321 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1324 if (0) { case AST_LT
: const_func
= RTLIL::const_lt
; }
1325 if (0) { case AST_LE
: const_func
= RTLIL::const_le
; }
1326 if (0) { case AST_EQ
: const_func
= RTLIL::const_eq
; }
1327 if (0) { case AST_NE
: const_func
= RTLIL::const_ne
; }
1328 if (0) { case AST_EQX
: const_func
= RTLIL::const_eqx
; }
1329 if (0) { case AST_NEX
: const_func
= RTLIL::const_nex
; }
1330 if (0) { case AST_GE
: const_func
= RTLIL::const_ge
; }
1331 if (0) { case AST_GT
: const_func
= RTLIL::const_gt
; }
1332 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1333 int cmp_width
= std::max(children
[0]->bits
.size(), children
[1]->bits
.size());
1334 bool cmp_signed
= children
[0]->is_signed
&& children
[1]->is_signed
;
1335 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(cmp_width
, cmp_signed
),
1336 children
[1]->bitsAsConst(cmp_width
, cmp_signed
), cmp_signed
, cmp_signed
, 1);
1337 newNode
= mkconst_bits(y
.bits
, false);
1340 if (0) { case AST_ADD
: const_func
= RTLIL::const_add
; }
1341 if (0) { case AST_SUB
: const_func
= RTLIL::const_sub
; }
1342 if (0) { case AST_MUL
: const_func
= RTLIL::const_mul
; }
1343 if (0) { case AST_DIV
: const_func
= RTLIL::const_div
; }
1344 if (0) { case AST_MOD
: const_func
= RTLIL::const_mod
; }
1345 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1346 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(width_hint
, sign_hint
),
1347 children
[1]->bitsAsConst(width_hint
, sign_hint
), sign_hint
, sign_hint
, width_hint
);
1348 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1351 if (0) { case AST_POS
: const_func
= RTLIL::const_pos
; }
1352 if (0) { case AST_NEG
: const_func
= RTLIL::const_neg
; }
1353 if (children
[0]->type
== AST_CONSTANT
) {
1354 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(width_hint
, sign_hint
), dummy_arg
, sign_hint
, false, width_hint
);
1355 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1359 if (children
[0]->type
== AST_CONSTANT
) {
1360 bool found_sure_true
= false;
1361 bool found_maybe_true
= false;
1362 for (auto &bit
: children
[0]->bits
) {
1363 if (bit
== RTLIL::State::S1
)
1364 found_sure_true
= true;
1365 if (bit
> RTLIL::State::S1
)
1366 found_maybe_true
= true;
1368 AstNode
*choice
= NULL
;
1369 if (found_sure_true
)
1370 choice
= children
[1];
1371 else if (!found_maybe_true
)
1372 choice
= children
[2];
1373 if (choice
!= NULL
&& choice
->type
== AST_CONSTANT
) {
1374 RTLIL::Const y
= choice
->bitsAsConst(width_hint
, sign_hint
);
1375 if (choice
->is_string
&& y
.bits
.size() % 8 == 0 && sign_hint
== false)
1376 newNode
= mkconst_str(y
.bits
);
1378 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1379 } else if (children
[1]->type
== AST_CONSTANT
&& children
[2]->type
== AST_CONSTANT
) {
1380 RTLIL::Const a
= children
[1]->bitsAsConst(width_hint
, sign_hint
);
1381 RTLIL::Const b
= children
[2]->bitsAsConst(width_hint
, sign_hint
);
1382 assert(a
.bits
.size() == b
.bits
.size());
1383 for (size_t i
= 0; i
< a
.bits
.size(); i
++)
1384 if (a
.bits
[i
] != b
.bits
[i
])
1385 a
.bits
[i
] = RTLIL::State::Sx
;
1386 newNode
= mkconst_bits(a
.bits
, sign_hint
);
1391 string_op
= !children
.empty();
1392 for (auto it
= children
.begin(); it
!= children
.end(); it
++) {
1393 if ((*it
)->type
!= AST_CONSTANT
)
1395 if (!(*it
)->is_string
)
1397 tmp_bits
.insert(tmp_bits
.end(), (*it
)->bits
.begin(), (*it
)->bits
.end());
1399 newNode
= string_op
? mkconst_str(tmp_bits
) : mkconst_bits(tmp_bits
, false);
1402 if (children
.at(0)->type
!= AST_CONSTANT
|| children
.at(1)->type
!= AST_CONSTANT
)
1404 for (int i
= 0; i
< children
[0]->bitsAsConst().as_int(); i
++)
1405 tmp_bits
.insert(tmp_bits
.end(), children
.at(1)->bits
.begin(), children
.at(1)->bits
.end());
1406 newNode
= children
.at(1)->is_string
? mkconst_str(tmp_bits
) : mkconst_bits(tmp_bits
, false);
1414 // if any of the above set 'newNode' -> use 'newNode' as template to update 'this'
1417 // fprintf(stderr, "----\n");
1418 // dumpAst(stderr, "- ");
1419 // newNode->dumpAst(stderr, "+ ");
1420 assert(newNode
!= NULL
);
1421 newNode
->filename
= filename
;
1422 newNode
->linenum
= linenum
;
1423 newNode
->cloneInto(this);
1425 did_something
= true;
1428 return did_something
;
1431 static void replace_result_wire_name_in_function(AstNode
*node
, std::string
&from
, std::string
&to
)
1433 for (auto &it
: node
->children
)
1434 replace_result_wire_name_in_function(it
, from
, to
);
1435 if (node
->str
== from
)
1439 // annotate the names of all wires and other named objects in a generate block
1440 void AstNode::expand_genblock(std::string index_var
, std::string prefix
, std::map
<std::string
, std::string
> &name_map
)
1442 if (!index_var
.empty() && type
== AST_IDENTIFIER
&& str
== index_var
) {
1443 current_scope
[index_var
]->children
[0]->cloneInto(this);
1447 if ((type
== AST_IDENTIFIER
|| type
== AST_FCALL
|| type
== AST_TCALL
) && name_map
.count(str
) > 0)
1448 str
= name_map
[str
];
1450 std::map
<std::string
, std::string
> backup_name_map
;
1452 for (size_t i
= 0; i
< children
.size(); i
++) {
1453 AstNode
*child
= children
[i
];
1454 if (child
->type
== AST_WIRE
|| child
->type
== AST_MEMORY
|| child
->type
== AST_PARAMETER
|| child
->type
== AST_LOCALPARAM
||
1455 child
->type
== AST_FUNCTION
|| child
->type
== AST_TASK
|| child
->type
== AST_CELL
) {
1456 if (backup_name_map
.size() == 0)
1457 backup_name_map
= name_map
;
1458 std::string new_name
= prefix
[0] == '\\' ? prefix
.substr(1) : prefix
;
1459 size_t pos
= child
->str
.rfind('.');
1460 if (pos
== std::string::npos
)
1461 pos
= child
->str
[0] == '\\' ? 1 : 0;
1464 new_name
= child
->str
.substr(0, pos
) + new_name
+ child
->str
.substr(pos
);
1465 if (new_name
[0] != '$' && new_name
[0] != '\\')
1466 new_name
= prefix
[0] + new_name
;
1467 name_map
[child
->str
] = new_name
;
1468 if (child
->type
== AST_FUNCTION
)
1469 replace_result_wire_name_in_function(child
, child
->str
, new_name
);
1471 child
->str
= new_name
;
1472 current_scope
[new_name
] = child
;
1476 for (size_t i
= 0; i
< children
.size(); i
++) {
1477 AstNode
*child
= children
[i
];
1478 if (child
->type
!= AST_FUNCTION
&& child
->type
!= AST_TASK
)
1479 child
->expand_genblock(index_var
, prefix
, name_map
);
1482 if (backup_name_map
.size() > 0)
1483 name_map
.swap(backup_name_map
);
1486 // rename stuff (used when tasks of functions are instanciated)
1487 void AstNode::replace_ids(std::map
<std::string
, std::string
> &rules
)
1489 if (type
== AST_IDENTIFIER
&& rules
.count(str
) > 0)
1491 for (auto child
: children
)
1492 child
->replace_ids(rules
);
1495 // find memories that should be replaced by registers
1496 void AstNode::mem2reg_as_needed_pass1(std::map
<AstNode
*, std::set
<std::string
>> &mem2reg_places
,
1497 std::map
<AstNode
*, uint32_t> &mem2reg_candidates
, std::map
<AstNode
*, uint32_t> &proc_flags
, uint32_t &flags
)
1499 uint32_t children_flags
= 0;
1500 int ignore_children_counter
= 0;
1502 if (type
== AST_ASSIGN
|| type
== AST_ASSIGN_LE
|| type
== AST_ASSIGN_EQ
)
1504 if (children
[0]->type
== AST_IDENTIFIER
&& children
[0]->id2ast
&& children
[0]->id2ast
->type
== AST_MEMORY
)
1506 AstNode
*mem
= children
[0]->id2ast
;
1508 // activate mem2reg if this is assigned in an async proc
1509 if (flags
& AstNode::MEM2REG_FL_ASYNC
) {
1510 if (!(mem2reg_candidates
[mem
] & AstNode::MEM2REG_FL_SET_ASYNC
))
1511 mem2reg_places
[mem
].insert(stringf("%s:%d", filename
.c_str(), linenum
));
1512 mem2reg_candidates
[mem
] |= AstNode::MEM2REG_FL_SET_ASYNC
;
1515 // remember if this is assigned blocking (=)
1516 if (type
== AST_ASSIGN_EQ
) {
1517 if (!(proc_flags
[mem
] & AstNode::MEM2REG_FL_EQ1
))
1518 mem2reg_places
[mem
].insert(stringf("%s:%d", filename
.c_str(), linenum
));
1519 proc_flags
[mem
] |= AstNode::MEM2REG_FL_EQ1
;
1522 // remember where this is
1523 if (flags
& MEM2REG_FL_INIT
) {
1524 if (!(mem2reg_candidates
[mem
] & AstNode::MEM2REG_FL_SET_INIT
))
1525 mem2reg_places
[mem
].insert(stringf("%s:%d", filename
.c_str(), linenum
));
1526 mem2reg_candidates
[mem
] |= AstNode::MEM2REG_FL_SET_INIT
;
1528 if (!(mem2reg_candidates
[mem
] & AstNode::MEM2REG_FL_SET_ELSE
))
1529 mem2reg_places
[mem
].insert(stringf("%s:%d", filename
.c_str(), linenum
));
1530 mem2reg_candidates
[mem
] |= AstNode::MEM2REG_FL_SET_ELSE
;
1534 ignore_children_counter
= 1;
1537 if (type
== AST_IDENTIFIER
&& id2ast
&& id2ast
->type
== AST_MEMORY
)
1539 AstNode
*mem
= id2ast
;
1541 // flag if used after blocking assignment (in same proc)
1542 if ((proc_flags
[mem
] & AstNode::MEM2REG_FL_EQ1
) && !(mem2reg_candidates
[mem
] & AstNode::MEM2REG_FL_EQ2
)) {
1543 mem2reg_places
[mem
].insert(stringf("%s:%d", filename
.c_str(), linenum
));
1544 mem2reg_candidates
[mem
] |= AstNode::MEM2REG_FL_EQ2
;
1548 // also activate if requested, either by using mem2reg attribute or by declaring array as 'wire' instead of 'reg'
1549 if (type
== AST_MEMORY
&& (get_bool_attribute("\\mem2reg") || (flags
& AstNode::MEM2REG_FL_ALL
) || !is_reg
))
1550 mem2reg_candidates
[this] |= AstNode::MEM2REG_FL_FORCED
;
1552 if (type
== AST_MODULE
&& get_bool_attribute("\\mem2reg"))
1553 children_flags
|= AstNode::MEM2REG_FL_ALL
;
1555 std::map
<AstNode
*, uint32_t> *proc_flags_p
= NULL
;
1557 if (type
== AST_ALWAYS
) {
1558 int count_edge_events
= 0;
1559 for (auto child
: children
)
1560 if (child
->type
== AST_POSEDGE
|| child
->type
== AST_NEGEDGE
)
1561 count_edge_events
++;
1562 if (count_edge_events
!= 1)
1563 children_flags
|= AstNode::MEM2REG_FL_ASYNC
;
1564 proc_flags_p
= new std::map
<AstNode
*, uint32_t>;
1567 if (type
== AST_INITIAL
) {
1568 children_flags
|= AstNode::MEM2REG_FL_INIT
;
1569 proc_flags_p
= new std::map
<AstNode
*, uint32_t>;
1572 uint32_t backup_flags
= flags
;
1573 flags
|= children_flags
;
1574 assert((flags
& ~0x000000ff) == 0);
1576 for (auto child
: children
)
1577 if (ignore_children_counter
> 0)
1578 ignore_children_counter
--;
1579 else if (proc_flags_p
)
1580 child
->mem2reg_as_needed_pass1(mem2reg_places
, mem2reg_candidates
, *proc_flags_p
, flags
);
1582 child
->mem2reg_as_needed_pass1(mem2reg_places
, mem2reg_candidates
, proc_flags
, flags
);
1584 flags
&= ~children_flags
| backup_flags
;
1587 for (auto it
: *proc_flags_p
)
1588 assert((it
.second
& ~0xff000000) == 0);
1589 delete proc_flags_p
;
1593 // actually replace memories with registers
1594 void AstNode::mem2reg_as_needed_pass2(std::set
<AstNode
*> &mem2reg_set
, AstNode
*mod
, AstNode
*block
)
1596 if (type
== AST_BLOCK
)
1599 if ((type
== AST_ASSIGN_LE
|| type
== AST_ASSIGN_EQ
) && block
!= NULL
&& children
[0]->id2ast
&&
1600 mem2reg_set
.count(children
[0]->id2ast
) > 0 && children
[0]->children
[0]->children
[0]->type
!= AST_CONSTANT
)
1602 std::stringstream sstr
;
1603 sstr
<< "$mem2reg_wr$" << children
[0]->str
<< "$" << filename
<< ":" << linenum
<< "$" << (RTLIL::autoidx
++);
1604 std::string id_addr
= sstr
.str() + "_ADDR", id_data
= sstr
.str() + "_DATA";
1606 int mem_width
, mem_size
, addr_bits
;
1607 children
[0]->id2ast
->meminfo(mem_width
, mem_size
, addr_bits
);
1609 AstNode
*wire_addr
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(addr_bits
-1, true), mkconst_int(0, true)));
1610 wire_addr
->str
= id_addr
;
1611 wire_addr
->is_reg
= true;
1612 wire_addr
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
1613 mod
->children
.push_back(wire_addr
);
1614 while (wire_addr
->simplify(true, false, false, 1, -1, false)) { }
1616 AstNode
*wire_data
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
1617 wire_data
->str
= id_data
;
1618 wire_data
->is_reg
= true;
1619 wire_data
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
1620 mod
->children
.push_back(wire_data
);
1621 while (wire_data
->simplify(true, false, false, 1, -1, false)) { }
1623 assert(block
!= NULL
);
1624 size_t assign_idx
= 0;
1625 while (assign_idx
< block
->children
.size() && block
->children
[assign_idx
] != this)
1627 assert(assign_idx
< block
->children
.size());
1629 AstNode
*assign_addr
= new AstNode(AST_ASSIGN_EQ
, new AstNode(AST_IDENTIFIER
), children
[0]->children
[0]->children
[0]->clone());
1630 assign_addr
->children
[0]->str
= id_addr
;
1631 block
->children
.insert(block
->children
.begin()+assign_idx
+1, assign_addr
);
1633 AstNode
*case_node
= new AstNode(AST_CASE
, new AstNode(AST_IDENTIFIER
));
1634 case_node
->children
[0]->str
= id_addr
;
1635 for (int i
= 0; i
< mem_size
; i
++) {
1636 if (children
[0]->children
[0]->children
[0]->type
== AST_CONSTANT
&& int(children
[0]->children
[0]->children
[0]->integer
) != i
)
1638 AstNode
*cond_node
= new AstNode(AST_COND
, AstNode::mkconst_int(i
, false, addr_bits
), new AstNode(AST_BLOCK
));
1639 AstNode
*assign_reg
= new AstNode(type
, new AstNode(AST_IDENTIFIER
), new AstNode(AST_IDENTIFIER
));
1640 assign_reg
->children
[0]->str
= stringf("%s[%d]", children
[0]->str
.c_str(), i
);
1641 assign_reg
->children
[1]->str
= id_data
;
1642 cond_node
->children
[1]->children
.push_back(assign_reg
);
1643 case_node
->children
.push_back(cond_node
);
1645 block
->children
.insert(block
->children
.begin()+assign_idx
+2, case_node
);
1647 children
[0]->delete_children();
1648 children
[0]->range_valid
= false;
1649 children
[0]->id2ast
= NULL
;
1650 children
[0]->str
= id_data
;
1651 type
= AST_ASSIGN_EQ
;
1654 if (type
== AST_IDENTIFIER
&& id2ast
&& mem2reg_set
.count(id2ast
) > 0)
1656 if (children
[0]->children
[0]->type
== AST_CONSTANT
)
1658 int id
= children
[0]->children
[0]->integer
;
1659 str
= stringf("%s[%d]", str
.c_str(), id
);
1662 range_valid
= false;
1667 std::stringstream sstr
;
1668 sstr
<< "$mem2reg_rd$" << children
[0]->str
<< "$" << filename
<< ":" << linenum
<< "$" << (RTLIL::autoidx
++);
1669 std::string id_addr
= sstr
.str() + "_ADDR", id_data
= sstr
.str() + "_DATA";
1671 int mem_width
, mem_size
, addr_bits
;
1672 id2ast
->meminfo(mem_width
, mem_size
, addr_bits
);
1674 AstNode
*wire_addr
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(addr_bits
-1, true), mkconst_int(0, true)));
1675 wire_addr
->str
= id_addr
;
1676 wire_addr
->is_reg
= true;
1678 wire_addr
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
1679 mod
->children
.push_back(wire_addr
);
1680 while (wire_addr
->simplify(true, false, false, 1, -1, false)) { }
1682 AstNode
*wire_data
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
1683 wire_data
->str
= id_data
;
1684 wire_data
->is_reg
= true;
1686 wire_data
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
1687 mod
->children
.push_back(wire_data
);
1688 while (wire_data
->simplify(true, false, false, 1, -1, false)) { }
1690 AstNode
*assign_addr
= new AstNode(block
? AST_ASSIGN_EQ
: AST_ASSIGN
, new AstNode(AST_IDENTIFIER
), children
[0]->children
[0]->clone());
1691 assign_addr
->children
[0]->str
= id_addr
;
1693 AstNode
*case_node
= new AstNode(AST_CASE
, new AstNode(AST_IDENTIFIER
));
1694 case_node
->children
[0]->str
= id_addr
;
1696 for (int i
= 0; i
< mem_size
; i
++) {
1697 if (children
[0]->children
[0]->type
== AST_CONSTANT
&& int(children
[0]->children
[0]->integer
) != i
)
1699 AstNode
*cond_node
= new AstNode(AST_COND
, AstNode::mkconst_int(i
, false, addr_bits
), new AstNode(AST_BLOCK
));
1700 AstNode
*assign_reg
= new AstNode(AST_ASSIGN_EQ
, new AstNode(AST_IDENTIFIER
), new AstNode(AST_IDENTIFIER
));
1701 assign_reg
->children
[0]->str
= id_data
;
1702 assign_reg
->children
[1]->str
= stringf("%s[%d]", str
.c_str(), i
);
1703 cond_node
->children
[1]->children
.push_back(assign_reg
);
1704 case_node
->children
.push_back(cond_node
);
1707 std::vector
<RTLIL::State
> x_bits
;
1708 for (int i
= 0; i
< mem_width
; i
++)
1709 x_bits
.push_back(RTLIL::State::Sx
);
1711 AstNode
*cond_node
= new AstNode(AST_COND
, new AstNode(AST_DEFAULT
), new AstNode(AST_BLOCK
));
1712 AstNode
*assign_reg
= new AstNode(AST_ASSIGN_EQ
, new AstNode(AST_IDENTIFIER
), AstNode::mkconst_bits(x_bits
, false));
1713 assign_reg
->children
[0]->str
= id_data
;
1714 cond_node
->children
[1]->children
.push_back(assign_reg
);
1715 case_node
->children
.push_back(cond_node
);
1719 size_t assign_idx
= 0;
1720 while (assign_idx
< block
->children
.size() && !block
->children
[assign_idx
]->contains(this))
1722 assert(assign_idx
< block
->children
.size());
1723 block
->children
.insert(block
->children
.begin()+assign_idx
, case_node
);
1724 block
->children
.insert(block
->children
.begin()+assign_idx
, assign_addr
);
1728 AstNode
*proc
= new AstNode(AST_ALWAYS
, new AstNode(AST_BLOCK
));
1729 proc
->children
[0]->children
.push_back(case_node
);
1730 mod
->children
.push_back(proc
);
1731 mod
->children
.push_back(assign_addr
);
1735 range_valid
= false;
1741 assert(id2ast
== NULL
|| mem2reg_set
.count(id2ast
) == 0);
1743 auto children_list
= children
;
1744 for (size_t i
= 0; i
< children_list
.size(); i
++)
1745 children_list
[i
]->mem2reg_as_needed_pass2(mem2reg_set
, mod
, block
);
1748 // calulate memory dimensions
1749 void AstNode::meminfo(int &mem_width
, int &mem_size
, int &addr_bits
)
1751 assert(type
== AST_MEMORY
);
1753 mem_width
= children
[0]->range_left
- children
[0]->range_right
+ 1;
1754 mem_size
= children
[1]->range_left
- children
[1]->range_right
;
1758 mem_size
+= std::min(children
[1]->range_left
, children
[1]->range_right
) + 1;
1761 while ((1 << addr_bits
) < mem_size
)