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::set
<AstNode
*> mem2reg_set
, mem2reg_candidates
;
60 mem2reg_as_needed_pass1(mem2reg_set
, mem2reg_candidates
, false, false, flag_mem2reg
);
62 for (auto node
: mem2reg_set
)
64 int mem_width
, mem_size
, addr_bits
;
65 node
->meminfo(mem_width
, mem_size
, addr_bits
);
67 for (int i
= 0; i
< mem_size
; i
++) {
68 AstNode
*reg
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
,
69 mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
70 reg
->str
= stringf("%s[%d]", node
->str
.c_str(), i
);
72 reg
->is_signed
= node
->is_signed
;
73 children
.push_back(reg
);
74 while (reg
->simplify(true, false, false, 1, -1, false)) { }
78 mem2reg_as_needed_pass2(mem2reg_set
, this, NULL
);
80 for (size_t i
= 0; i
< children
.size(); i
++) {
81 if (mem2reg_set
.count(children
[i
]) > 0) {
83 children
.erase(children
.begin() + (i
--));
88 while (simplify(const_fold
, at_zero
, in_lvalue
, 2, width_hint
, sign_hint
)) { }
92 current_filename
= filename
;
93 set_line_num(linenum
);
95 // we do not look inside a task or function
96 // (but as soon as a task of function is instanciated we process the generated AST as usual)
97 if (type
== AST_FUNCTION
|| type
== AST_TASK
)
100 // deactivate all calls non-synthesis system taks
101 if ((type
== AST_FCALL
|| type
== AST_TCALL
) && (str
== "$display" || str
== "$stop" || str
== "$finish")) {
106 // activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
107 if (type
== AST_WIRE
|| type
== AST_PARAMETER
|| type
== AST_LOCALPARAM
|| type
== AST_DEFPARAM
|| type
== AST_PARASET
|| type
== AST_RANGE
|| type
== AST_PREFIX
)
109 if (type
== AST_IDENTIFIER
&& current_scope
.count(str
) > 0 && (current_scope
[str
]->type
== AST_PARAMETER
|| current_scope
[str
]->type
== AST_LOCALPARAM
))
112 std::map
<std::string
, AstNode
*> backup_scope
;
114 // create name resolution entries for all objects with names
115 // also merge multiple declarations for the same wire (e.g. "output foobar; reg foobar;")
116 if (type
== AST_MODULE
) {
117 current_scope
.clear();
118 std::map
<std::string
, AstNode
*> this_wire_scope
;
119 for (size_t i
= 0; i
< children
.size(); i
++) {
120 AstNode
*node
= children
[i
];
121 if (node
->type
== AST_WIRE
) {
122 if (this_wire_scope
.count(node
->str
) > 0) {
123 AstNode
*first_node
= this_wire_scope
[node
->str
];
124 if (!node
->is_input
&& !node
->is_output
&& node
->is_reg
&& node
->children
.size() == 0)
125 goto wires_are_compatible
;
126 if (first_node
->children
.size() != node
->children
.size())
127 goto wires_are_incompatible
;
128 for (size_t j
= 0; j
< node
->children
.size(); j
++) {
129 AstNode
*n1
= first_node
->children
[j
], *n2
= node
->children
[j
];
130 if (n1
->type
== AST_RANGE
&& n2
->type
== AST_RANGE
&& n1
->range_valid
&& n2
->range_valid
) {
131 if (n1
->range_left
!= n2
->range_left
)
132 goto wires_are_incompatible
;
133 if (n1
->range_right
!= n2
->range_right
)
134 goto wires_are_incompatible
;
135 } else if (*n1
!= *n2
)
136 goto wires_are_incompatible
;
138 if (first_node
->range_left
!= node
->range_left
)
139 goto wires_are_incompatible
;
140 if (first_node
->range_right
!= node
->range_right
)
141 goto wires_are_incompatible
;
142 if (first_node
->port_id
== 0 && (node
->is_input
|| node
->is_output
))
143 goto wires_are_incompatible
;
144 wires_are_compatible
:
146 first_node
->is_input
= true;
148 first_node
->is_output
= true;
150 first_node
->is_reg
= true;
152 first_node
->is_signed
= true;
153 for (auto &it
: node
->attributes
) {
154 if (first_node
->attributes
.count(it
.first
) > 0)
155 delete first_node
->attributes
[it
.first
];
156 first_node
->attributes
[it
.first
] = it
.second
->clone();
158 children
.erase(children
.begin()+(i
--));
159 did_something
= true;
163 this_wire_scope
[node
->str
] = node
;
165 wires_are_incompatible
:
166 if (node
->type
== AST_PARAMETER
|| node
->type
== AST_LOCALPARAM
|| node
->type
== AST_WIRE
|| node
->type
== AST_AUTOWIRE
|| node
->type
== AST_GENVAR
||
167 node
->type
== AST_MEMORY
|| node
->type
== AST_FUNCTION
|| node
->type
== AST_TASK
|| node
->type
== AST_CELL
) {
168 backup_scope
[node
->str
] = current_scope
[node
->str
];
169 current_scope
[node
->str
] = node
;
174 auto backup_current_block
= current_block
;
175 auto backup_current_block_child
= current_block_child
;
176 auto backup_current_top_block
= current_top_block
;
178 int backup_width_hint
= width_hint
;
179 bool backup_sign_hint
= sign_hint
;
181 bool detect_width_simple
= false;
182 bool child_0_is_self_determined
= false;
183 bool child_1_is_self_determined
= false;
184 bool children_are_self_determined
= false;
185 bool reset_width_after_children
= false;
192 while (children
[0]->simplify(false, false, true, stage
, -1, false) == true) { }
193 while (children
[1]->simplify(false, false, false, stage
, -1, false) == true) { }
194 children
[0]->detectSignWidth(backup_width_hint
, backup_sign_hint
);
195 children
[1]->detectSignWidth(width_hint
, sign_hint
);
196 width_hint
= std::max(width_hint
, backup_width_hint
);
197 child_0_is_self_determined
= true;
202 while (children
[0]->simplify(false, false, false, stage
, -1, false) == true) { }
203 children
[0]->detectSignWidth(width_hint
, sign_hint
);
204 if (children
.size() > 1) {
205 assert(children
[1]->type
== AST_RANGE
);
206 while (children
[1]->simplify(false, false, false, stage
, -1, false) == true) { }
207 if (!children
[1]->range_valid
)
208 log_error("Non-constant width range on parameter decl at %s:%d.\n", filename
.c_str(), linenum
);
209 width_hint
= std::max(width_hint
, children
[1]->range_left
- children
[1]->range_right
+ 1);
214 case AST_TO_UNSIGNED
:
220 case AST_REDUCE_XNOR
:
221 case AST_REDUCE_BOOL
:
222 detect_width_simple
= true;
223 children_are_self_determined
= true;
238 detect_width_simple
= true;
242 case AST_SHIFT_RIGHT
:
243 case AST_SHIFT_SLEFT
:
244 case AST_SHIFT_SRIGHT
:
246 detect_width_simple
= true;
247 child_1_is_self_determined
= true;
258 for (auto child
: children
) {
259 while (child
->simplify(false, false, in_lvalue
, stage
, -1, false) == true) { }
260 child
->detectSignWidthWorker(width_hint
, sign_hint
);
262 reset_width_after_children
= true;
268 detect_width_simple
= true;
269 children_are_self_determined
= true;
273 detect_width_simple
= true;
274 child_0_is_self_determined
= true;
278 detect_width_simple
= true;
279 children_are_self_determined
= true;
287 if (detect_width_simple
&& width_hint
< 0) {
288 for (auto child
: children
)
289 while (child
->simplify(false, false, in_lvalue
, stage
, -1, false) == true) { }
290 if (type
== AST_REPLICATE
)
291 while (children
[0]->simplify(true, false, in_lvalue
, stage
, -1, false) == true) { }
292 detectSignWidth(width_hint
, sign_hint
);
295 // simplify all children first
296 // (iterate by index as e.g. auto wires can add new children in the process)
297 for (size_t i
= 0; i
< children
.size(); i
++) {
298 bool did_something_here
= true;
299 if ((type
== AST_GENFOR
|| type
== AST_FOR
) && i
>= 3)
301 if (type
== AST_GENIF
&& i
>= 1)
303 if (type
== AST_GENBLOCK
)
305 if (type
== AST_PREFIX
&& i
>= 1)
307 while (did_something_here
&& i
< children
.size()) {
308 bool const_fold_here
= const_fold
, in_lvalue_here
= in_lvalue
;
309 int width_hint_here
= width_hint
;
310 bool sign_hint_here
= sign_hint
;
311 if (i
== 0 && type
== AST_REPLICATE
)
312 const_fold_here
= true;
313 if (type
== AST_PARAMETER
|| type
== AST_LOCALPARAM
)
314 const_fold_here
= true;
315 if (i
== 0 && (type
== AST_ASSIGN
|| type
== AST_ASSIGN_EQ
|| type
== AST_ASSIGN_LE
))
316 in_lvalue_here
= true;
317 if (type
== AST_BLOCK
) {
318 current_block
= this;
319 current_block_child
= children
[i
];
321 if ((type
== AST_ALWAYS
|| type
== AST_INITIAL
) && children
[i
]->type
== AST_BLOCK
)
322 current_top_block
= children
[i
];
323 if (i
== 0 && child_0_is_self_determined
)
324 width_hint_here
= -1, sign_hint_here
= false;
325 if (i
== 1 && child_1_is_self_determined
)
326 width_hint_here
= -1, sign_hint_here
= false;
327 if (children_are_self_determined
)
328 width_hint_here
= -1, sign_hint_here
= false;
329 did_something_here
= children
[i
]->simplify(const_fold_here
, at_zero
, in_lvalue_here
, stage
, width_hint_here
, sign_hint_here
);
330 if (did_something_here
)
331 did_something
= true;
334 for (auto &attr
: attributes
) {
335 while (attr
.second
->simplify(true, false, false, stage
, -1, false)) { }
338 if (reset_width_after_children
) {
339 width_hint
= backup_width_hint
;
340 sign_hint
= backup_sign_hint
;
342 detectSignWidth(width_hint
, sign_hint
);
345 current_block
= backup_current_block
;
346 current_block_child
= backup_current_block_child
;
347 current_top_block
= backup_current_top_block
;
349 for (auto it
= backup_scope
.begin(); it
!= backup_scope
.end(); it
++) {
350 if (it
->second
== NULL
)
351 current_scope
.erase(it
->first
);
353 current_scope
[it
->first
] = it
->second
;
356 current_filename
= filename
;
357 set_line_num(linenum
);
359 if (type
== AST_MODULE
)
360 current_scope
.clear();
362 // convert defparam nodes to cell parameters
363 if (type
== AST_DEFPARAM
&& !str
.empty()) {
364 size_t pos
= str
.rfind('.');
365 if (pos
== std::string::npos
)
366 log_error("Defparam `%s' does not contain a dot (module/parameter seperator) at %s:%d!\n",
367 RTLIL::id2cstr(str
.c_str()), filename
.c_str(), linenum
);
368 std::string modname
= str
.substr(0, pos
), paraname
= "\\" + str
.substr(pos
+1);
369 if (current_scope
.count(modname
) == 0 || current_scope
.at(modname
)->type
!= AST_CELL
)
370 log_error("Can't find cell for defparam `%s . %s` at %s:%d!\n", RTLIL::id2cstr(modname
), RTLIL::id2cstr(paraname
), filename
.c_str(), linenum
);
371 AstNode
*cell
= current_scope
.at(modname
), *paraset
= clone();
372 cell
->children
.insert(cell
->children
.begin() + 1, paraset
);
373 paraset
->type
= AST_PARASET
;
374 paraset
->str
= paraname
;
378 // resolve constant prefixes
379 if (type
== AST_PREFIX
) {
380 if (children
[0]->type
!= AST_CONSTANT
) {
381 // dumpAst(NULL, "> ");
382 log_error("Index in generate block prefix syntax at %s:%d is not constant!\n", filename
.c_str(), linenum
);
384 assert(children
[1]->type
== AST_IDENTIFIER
);
385 newNode
= children
[1]->clone();
386 newNode
->str
= stringf("%s[%d].%s", str
.c_str(), children
[0]->integer
, children
[1]->str
.c_str());
390 // annotate constant ranges
391 if (type
== AST_RANGE
) {
392 bool old_range_valid
= range_valid
;
396 assert(children
.size() >= 1);
397 if (children
[0]->type
== AST_CONSTANT
) {
399 range_left
= children
[0]->integer
;
400 if (children
.size() == 1)
401 range_right
= range_left
;
403 if (children
.size() >= 2) {
404 if (children
[1]->type
== AST_CONSTANT
)
405 range_right
= children
[1]->integer
;
409 if (old_range_valid
!= range_valid
)
410 did_something
= true;
411 if (range_valid
&& range_left
>= 0 && range_right
> range_left
) {
412 int tmp
= range_right
;
413 range_right
= range_left
;
418 // annotate wires with their ranges
419 if (type
== AST_WIRE
) {
420 if (children
.size() > 0) {
421 if (children
[0]->range_valid
) {
423 did_something
= true;
425 range_left
= children
[0]->range_left
;
426 range_right
= children
[0]->range_right
;
430 did_something
= true;
437 // trim/extend parameters
438 if ((type
== AST_PARAMETER
|| type
== AST_LOCALPARAM
) && children
[0]->type
== AST_CONSTANT
&& children
.size() > 1) {
439 if (!children
[1]->range_valid
)
440 log_error("Non-constant width range on parameter decl at %s:%d.\n", filename
.c_str(), linenum
);
441 int width
= children
[1]->range_left
- children
[1]->range_right
+ 1;
442 if (width
!= int(children
[0]->bits
.size())) {
443 RTLIL::SigSpec
sig(children
[0]->bits
);
444 sig
.extend_u0(width
, children
[0]->is_signed
);
446 children
[0] = mkconst_bits(sig
.as_const().bits
, children
[0]->is_signed
);
448 children
[0]->is_signed
= is_signed
;
451 // annotate identifiers using scope resolution and create auto-wires as needed
452 if (type
== AST_IDENTIFIER
) {
453 if (current_scope
.count(str
) == 0) {
454 for (auto node
: current_ast_mod
->children
) {
455 if ((node
->type
== AST_PARAMETER
|| node
->type
== AST_LOCALPARAM
|| node
->type
== AST_WIRE
|| node
->type
== AST_AUTOWIRE
|| node
->type
== AST_GENVAR
||
456 node
->type
== AST_MEMORY
|| node
->type
== AST_FUNCTION
|| node
->type
== AST_TASK
) && str
== node
->str
) {
457 current_scope
[node
->str
] = node
;
462 if (current_scope
.count(str
) == 0) {
463 log("Warning: Creating auto-wire `%s' in module `%s'.\n", str
.c_str(), current_ast_mod
->str
.c_str());
464 AstNode
*auto_wire
= new AstNode(AST_AUTOWIRE
);
465 auto_wire
->str
= str
;
466 current_ast_mod
->children
.push_back(auto_wire
);
467 current_scope
[str
] = auto_wire
;
468 did_something
= true;
470 id2ast
= current_scope
[str
];
473 // unroll for loops and generate-for blocks
474 if ((type
== AST_GENFOR
|| type
== AST_FOR
) && children
.size() != 0)
476 AstNode
*init_ast
= children
[0];
477 AstNode
*while_ast
= children
[1];
478 AstNode
*next_ast
= children
[2];
479 AstNode
*body_ast
= children
[3];
481 if (init_ast
->type
!= AST_ASSIGN_EQ
)
482 log_error("Unsupported 1st expression of generate for-loop at %s:%d!\n", filename
.c_str(), linenum
);
483 if (next_ast
->type
!= AST_ASSIGN_EQ
)
484 log_error("Unsupported 3rd expression of generate for-loop at %s:%d!\n", filename
.c_str(), linenum
);
486 if (type
== AST_GENFOR
) {
487 if (init_ast
->children
[0]->id2ast
== NULL
|| init_ast
->children
[0]->id2ast
->type
!= AST_GENVAR
)
488 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
);
489 if (next_ast
->children
[0]->id2ast
== NULL
|| next_ast
->children
[0]->id2ast
->type
!= AST_GENVAR
)
490 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
);
492 if (init_ast
->children
[0]->id2ast
== NULL
|| init_ast
->children
[0]->id2ast
->type
!= AST_WIRE
)
493 log_error("Left hand side of 1st expression of generate for-loop at %s:%d is not a register!\n", filename
.c_str(), linenum
);
494 if (next_ast
->children
[0]->id2ast
== NULL
|| next_ast
->children
[0]->id2ast
->type
!= AST_WIRE
)
495 log_error("Left hand side of 3rd expression of generate for-loop at %s:%d is not a register!\n", filename
.c_str(), linenum
);
498 if (init_ast
->children
[0]->id2ast
!= next_ast
->children
[0]->id2ast
)
499 log_error("Incompatible left-hand sides in 1st and 3rd expression of generate for-loop at %s:%d!\n", filename
.c_str(), linenum
);
501 // eval 1st expression
502 AstNode
*varbuf
= init_ast
->children
[1]->clone();
503 while (varbuf
->simplify(true, false, false, stage
, width_hint
, sign_hint
)) { }
505 if (varbuf
->type
!= AST_CONSTANT
)
506 log_error("Right hand side of 1st expression of generate for-loop at %s:%d is not constant!\n", filename
.c_str(), linenum
);
508 varbuf
= new AstNode(AST_LOCALPARAM
, varbuf
);
509 varbuf
->str
= init_ast
->children
[0]->str
;
511 AstNode
*backup_scope_varbuf
= current_scope
[varbuf
->str
];
512 current_scope
[varbuf
->str
] = varbuf
;
514 size_t current_block_idx
= 0;
515 if (type
== AST_FOR
) {
516 while (current_block_idx
< current_block
->children
.size() &&
517 current_block
->children
[current_block_idx
] != current_block_child
)
523 // eval 2nd expression
524 AstNode
*buf
= while_ast
->clone();
525 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
)) { }
527 if (buf
->type
!= AST_CONSTANT
)
528 log_error("2nd expression of generate for-loop at %s:%d is not constant!\n", filename
.c_str(), linenum
);
530 if (buf
->integer
== 0) {
537 int index
= varbuf
->children
[0]->integer
;
538 if (body_ast
->type
== AST_GENBLOCK
)
539 buf
= body_ast
->clone();
541 buf
= new AstNode(AST_GENBLOCK
, body_ast
->clone());
542 if (buf
->str
.empty()) {
543 std::stringstream sstr
;
544 sstr
<< "$genblock$" << filename
<< ":" << linenum
<< "$" << (RTLIL::autoidx
++);
545 buf
->str
= sstr
.str();
547 std::map
<std::string
, std::string
> name_map
;
548 std::stringstream sstr
;
549 sstr
<< buf
->str
<< "[" << index
<< "].";
550 buf
->expand_genblock(varbuf
->str
, sstr
.str(), name_map
);
552 if (type
== AST_GENFOR
) {
553 for (size_t i
= 0; i
< buf
->children
.size(); i
++)
554 current_ast_mod
->children
.push_back(buf
->children
[i
]);
556 for (size_t i
= 0; i
< buf
->children
.size(); i
++)
557 current_block
->children
.insert(current_block
->children
.begin() + current_block_idx
++, buf
->children
[i
]);
559 buf
->children
.clear();
562 // eval 3rd expression
563 buf
= next_ast
->children
[1]->clone();
564 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
)) { }
566 if (buf
->type
!= AST_CONSTANT
)
567 log_error("Right hand side of 3rd expression of generate for-loop at %s:%d is not constant!\n", filename
.c_str(), linenum
);
569 delete varbuf
->children
[0];
570 varbuf
->children
[0] = buf
;
573 current_scope
[varbuf
->str
] = backup_scope_varbuf
;
576 did_something
= true;
579 // simplify unconditional generate block
580 if (type
== AST_GENBLOCK
&& children
.size() != 0)
583 std::map
<std::string
, std::string
> name_map
;
584 expand_genblock(std::string(), str
+ ".", name_map
);
587 for (size_t i
= 0; i
< children
.size(); i
++)
588 current_ast_mod
->children
.push_back(children
[i
]);
591 did_something
= true;
594 // simplify generate-if blocks
595 if (type
== AST_GENIF
&& children
.size() != 0)
597 AstNode
*buf
= children
[0]->clone();
598 while (buf
->simplify(true, false, false, stage
, width_hint
, sign_hint
)) { }
599 if (buf
->type
!= AST_CONSTANT
) {
600 // for (auto f : log_files)
601 // dumpAst(f, "verilog-ast> ");
602 log_error("Condition for generate if at %s:%d is not constant!\n", filename
.c_str(), linenum
);
604 if (buf
->integer
!= 0) {
606 buf
= children
[1]->clone();
609 buf
= children
.size() > 2 ? children
[2]->clone() : NULL
;
614 if (buf
->type
!= AST_GENBLOCK
)
615 buf
= new AstNode(AST_GENBLOCK
, buf
);
617 if (!buf
->str
.empty()) {
618 std::map
<std::string
, std::string
> name_map
;
619 buf
->expand_genblock(std::string(), buf
->str
+ ".", name_map
);
622 for (size_t i
= 0; i
< buf
->children
.size(); i
++)
623 current_ast_mod
->children
.push_back(buf
->children
[i
]);
625 buf
->children
.clear();
630 did_something
= true;
633 // replace primitives with assignmens
634 if (type
== AST_PRIMITIVE
)
636 if (children
.size() < 2)
637 log_error("Insufficient number of arguments for primitive `%s' at %s:%d!\n",
638 str
.c_str(), filename
.c_str(), linenum
);
640 std::vector
<AstNode
*> children_list
;
641 for (auto child
: children
) {
642 assert(child
->type
== AST_ARGUMENT
);
643 assert(child
->children
.size() == 1);
644 children_list
.push_back(child
->children
[0]);
645 child
->children
.clear();
650 if (str
== "bufif0" || str
== "bufif1" || str
== "notif0" || str
== "notif1")
652 if (children_list
.size() != 3)
653 log_error("Invalid number of arguments for primitive `%s' at %s:%d!\n",
654 str
.c_str(), filename
.c_str(), linenum
);
656 std::vector
<RTLIL::State
> z_const(1, RTLIL::State::Sz
);
658 AstNode
*mux_input
= children_list
.at(1);
659 if (str
== "notif0" || str
== "notif1") {
660 mux_input
= new AstNode(AST_BIT_NOT
, mux_input
);
662 AstNode
*node
= new AstNode(AST_TERNARY
, children_list
.at(2));
663 if (str
== "bufif0") {
664 node
->children
.push_back(AstNode::mkconst_bits(z_const
, false));
665 node
->children
.push_back(mux_input
);
667 node
->children
.push_back(mux_input
);
668 node
->children
.push_back(AstNode::mkconst_bits(z_const
, false));
673 children
.push_back(children_list
.at(0));
674 children
.push_back(node
);
675 did_something
= true;
679 AstNodeType op_type
= AST_NONE
;
680 bool invert_results
= false;
683 op_type
= AST_BIT_AND
;
685 op_type
= AST_BIT_AND
, invert_results
= true;
687 op_type
= AST_BIT_OR
;
689 op_type
= AST_BIT_OR
, invert_results
= true;
691 op_type
= AST_BIT_XOR
;
693 op_type
= AST_BIT_XOR
, invert_results
= true;
697 op_type
= AST_POS
, invert_results
= true;
698 assert(op_type
!= AST_NONE
);
700 AstNode
*node
= children_list
[1];
701 if (op_type
!= AST_POS
)
702 for (size_t i
= 2; i
< children_list
.size(); i
++)
703 node
= new AstNode(op_type
, node
, children_list
[i
]);
705 node
= new AstNode(AST_BIT_NOT
, node
);
709 children
.push_back(children_list
[0]);
710 children
.push_back(node
);
711 did_something
= true;
715 // replace dynamic ranges in left-hand side expressions (e.g. "foo[bar] <= 1'b1;") with
716 // a big case block that selects the correct single-bit assignment.
717 if (type
== AST_ASSIGN_EQ
|| type
== AST_ASSIGN_LE
) {
718 if (children
[0]->type
!= AST_IDENTIFIER
|| children
[0]->children
.size() == 0)
719 goto skip_dynamic_range_lvalue_expansion
;
720 if (children
[0]->children
[0]->range_valid
|| did_something
)
721 goto skip_dynamic_range_lvalue_expansion
;
722 if (children
[0]->id2ast
== NULL
|| children
[0]->id2ast
->type
!= AST_WIRE
)
723 goto skip_dynamic_range_lvalue_expansion
;
724 if (!children
[0]->id2ast
->range_valid
)
725 goto skip_dynamic_range_lvalue_expansion
;
726 int source_width
= children
[0]->id2ast
->range_left
- children
[0]->id2ast
->range_right
+ 1;
727 int result_width
= 1;
728 AstNode
*shift_expr
= NULL
;
729 AstNode
*range
= children
[0]->children
[0];
730 if (range
->children
.size() == 1) {
731 shift_expr
= range
->children
[0]->clone();
733 shift_expr
= range
->children
[1]->clone();
734 AstNode
*left_at_zero_ast
= range
->children
[0]->clone();
735 AstNode
*right_at_zero_ast
= range
->children
[1]->clone();
736 while (left_at_zero_ast
->simplify(true, true, false, stage
, -1, false)) { }
737 while (right_at_zero_ast
->simplify(true, true, false, stage
, -1, false)) { }
738 if (left_at_zero_ast
->type
!= AST_CONSTANT
|| right_at_zero_ast
->type
!= AST_CONSTANT
)
739 log_error("Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n",
740 str
.c_str(), filename
.c_str(), linenum
);
741 result_width
= left_at_zero_ast
->integer
- right_at_zero_ast
->integer
+ 1;
743 did_something
= true;
744 newNode
= new AstNode(AST_CASE
, shift_expr
);
745 for (int i
= 0; i
<= source_width
-result_width
; i
++) {
746 int start_bit
= children
[0]->id2ast
->range_right
+ i
;
747 AstNode
*cond
= new AstNode(AST_COND
, mkconst_int(start_bit
, true));
748 AstNode
*lvalue
= children
[0]->clone();
749 lvalue
->delete_children();
750 lvalue
->children
.push_back(new AstNode(AST_RANGE
,
751 mkconst_int(start_bit
+result_width
-1, true), mkconst_int(start_bit
, true)));
752 cond
->children
.push_back(new AstNode(AST_BLOCK
, new AstNode(type
, lvalue
, children
[1]->clone())));
753 newNode
->children
.push_back(cond
);
757 skip_dynamic_range_lvalue_expansion
:;
759 // found right-hand side identifier for memory -> replace with memory read port
760 if (stage
> 1 && type
== AST_IDENTIFIER
&& id2ast
!= NULL
&& id2ast
->type
== AST_MEMORY
&& !in_lvalue
&&
761 children
[0]->type
== AST_RANGE
&& children
[0]->children
.size() == 1) {
762 newNode
= new AstNode(AST_MEMRD
, children
[0]->children
[0]->clone());
764 newNode
->id2ast
= id2ast
;
768 // assignment with memory in left-hand side expression -> replace with memory write port
769 if (stage
> 1 && (type
== AST_ASSIGN_EQ
|| type
== AST_ASSIGN_LE
) && children
[0]->type
== AST_IDENTIFIER
&&
770 children
[0]->children
.size() == 1 && children
[0]->id2ast
&& children
[0]->id2ast
->type
== AST_MEMORY
&&
771 children
[0]->id2ast
->children
.size() >= 2 && children
[0]->id2ast
->children
[0]->range_valid
&&
772 children
[0]->id2ast
->children
[1]->range_valid
)
774 std::stringstream sstr
;
775 sstr
<< "$memwr$" << children
[0]->str
<< "$" << filename
<< ":" << linenum
<< "$" << (RTLIL::autoidx
++);
776 std::string id_addr
= sstr
.str() + "_ADDR", id_data
= sstr
.str() + "_DATA", id_en
= sstr
.str() + "_EN";
778 if (type
== AST_ASSIGN_EQ
)
779 log("Warining: Blocking assignment to memory in line %s:%d is handled like a non-blocking assignment.\n",
780 filename
.c_str(), linenum
);
782 int mem_width
, mem_size
, addr_bits
;
783 children
[0]->id2ast
->meminfo(mem_width
, mem_size
, addr_bits
);
785 AstNode
*wire_addr
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(addr_bits
-1, true), mkconst_int(0, true)));
786 wire_addr
->str
= id_addr
;
787 current_ast_mod
->children
.push_back(wire_addr
);
788 current_scope
[wire_addr
->str
] = wire_addr
;
789 while (wire_addr
->simplify(true, false, false, 1, -1, false)) { }
791 AstNode
*wire_data
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
792 wire_data
->str
= id_data
;
793 current_ast_mod
->children
.push_back(wire_data
);
794 current_scope
[wire_data
->str
] = wire_data
;
795 while (wire_data
->simplify(true, false, false, 1, -1, false)) { }
797 AstNode
*wire_en
= new AstNode(AST_WIRE
);
798 wire_en
->str
= id_en
;
799 current_ast_mod
->children
.push_back(wire_en
);
800 current_scope
[wire_en
->str
] = wire_en
;
801 while (wire_en
->simplify(true, false, false, 1, -1, false)) { }
803 std::vector
<RTLIL::State
> x_bits
;
804 for (int i
= 0; i
< mem_width
; i
++)
805 x_bits
.push_back(RTLIL::State::Sx
);
807 AstNode
*assign_addr
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_bits(x_bits
, false));
808 assign_addr
->children
[0]->str
= id_addr
;
810 AstNode
*assign_data
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_bits(x_bits
, false));
811 assign_data
->children
[0]->str
= id_data
;
813 AstNode
*assign_en
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_int(0, false, 1));
814 assign_en
->children
[0]->str
= id_en
;
816 AstNode
*default_signals
= new AstNode(AST_BLOCK
);
817 default_signals
->children
.push_back(assign_addr
);
818 default_signals
->children
.push_back(assign_data
);
819 default_signals
->children
.push_back(assign_en
);
820 current_top_block
->children
.insert(current_top_block
->children
.begin(), default_signals
);
822 assign_addr
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), children
[0]->children
[0]->children
[0]->clone());
823 assign_addr
->children
[0]->str
= id_addr
;
825 assign_data
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), children
[1]->clone());
826 assign_data
->children
[0]->str
= id_data
;
828 assign_en
= new AstNode(AST_ASSIGN_LE
, new AstNode(AST_IDENTIFIER
), mkconst_int(1, false, 1));
829 assign_en
->children
[0]->str
= id_en
;
831 newNode
= new AstNode(AST_BLOCK
);
832 newNode
->children
.push_back(assign_addr
);
833 newNode
->children
.push_back(assign_data
);
834 newNode
->children
.push_back(assign_en
);
836 AstNode
*wrnode
= new AstNode(AST_MEMWR
);
837 wrnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
838 wrnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
839 wrnode
->children
.push_back(new AstNode(AST_IDENTIFIER
));
840 wrnode
->str
= children
[0]->str
;
841 wrnode
->children
[0]->str
= id_addr
;
842 wrnode
->children
[1]->str
= id_data
;
843 wrnode
->children
[2]->str
= id_en
;
844 current_ast_mod
->children
.push_back(wrnode
);
849 // replace function and task calls with the code from the function or task
850 if ((type
== AST_FCALL
|| type
== AST_TCALL
) && !str
.empty())
852 if (type
== AST_FCALL
) {
853 if (current_scope
.count(str
) == 0 || current_scope
[str
]->type
!= AST_FUNCTION
)
854 log_error("Can't resolve function name `%s' at %s:%d.\n", str
.c_str(), filename
.c_str(), linenum
);
856 if (type
== AST_TCALL
) {
857 if (current_scope
.count(str
) == 0 || current_scope
[str
]->type
!= AST_TASK
)
858 log_error("Can't resolve task name `%s' at %s:%d.\n", str
.c_str(), filename
.c_str(), linenum
);
861 AstNode
*decl
= current_scope
[str
];
862 std::stringstream sstr
;
863 sstr
<< "$func$" << str
<< "$" << filename
<< ":" << linenum
<< "$" << (RTLIL::autoidx
++) << "$";
864 std::string prefix
= sstr
.str();
866 size_t arg_count
= 0;
867 std::map
<std::string
, std::string
> replace_rules
;
869 if (current_block
== NULL
)
871 assert(type
== AST_FCALL
);
873 AstNode
*wire
= NULL
;
874 for (auto child
: decl
->children
)
875 if (child
->type
== AST_WIRE
&& child
->str
== str
)
876 wire
= child
->clone();
877 assert(wire
!= NULL
);
879 wire
->str
= prefix
+ str
;
881 wire
->is_input
= false;
882 wire
->is_output
= false;
884 current_ast_mod
->children
.push_back(wire
);
885 while (wire
->simplify(true, false, false, 1, -1, false)) { }
887 AstNode
*lvalue
= new AstNode(AST_IDENTIFIER
);
888 lvalue
->str
= wire
->str
;
890 AstNode
*always
= new AstNode(AST_ALWAYS
, new AstNode(AST_BLOCK
,
891 new AstNode(AST_ASSIGN_EQ
, lvalue
, clone())));
892 current_ast_mod
->children
.push_back(always
);
894 goto replace_fcall_with_id
;
897 for (auto child
: decl
->children
)
899 if (child
->type
== AST_WIRE
)
901 AstNode
*wire
= child
->clone();
902 wire
->str
= prefix
+ wire
->str
;
904 wire
->is_input
= false;
905 wire
->is_output
= false;
906 current_ast_mod
->children
.push_back(wire
);
907 while (wire
->simplify(true, false, false, 1, -1, false)) { }
909 replace_rules
[child
->str
] = wire
->str
;
911 if (child
->is_input
&& arg_count
< children
.size())
913 AstNode
*arg
= children
[arg_count
++]->clone();
914 AstNode
*wire_id
= new AstNode(AST_IDENTIFIER
);
915 wire_id
->str
= wire
->str
;
916 AstNode
*assign
= new AstNode(AST_ASSIGN_EQ
, wire_id
, arg
);
918 for (auto it
= current_block
->children
.begin(); it
!= current_block
->children
.end(); it
++) {
919 if (*it
!= current_block_child
)
921 current_block
->children
.insert(it
, assign
);
928 AstNode
*stmt
= child
->clone();
929 stmt
->replace_ids(replace_rules
);
931 for (auto it
= current_block
->children
.begin(); it
!= current_block
->children
.end(); it
++) {
932 if (*it
!= current_block_child
)
934 current_block
->children
.insert(it
, stmt
);
940 replace_fcall_with_id
:
941 if (type
== AST_FCALL
) {
943 type
= AST_IDENTIFIER
;
946 if (type
== AST_TCALL
)
948 did_something
= true;
951 // perform const folding when activated
952 if (const_fold
&& newNode
== NULL
)
954 std::vector
<RTLIL::State
> tmp_bits
;
955 RTLIL::Const (*const_func
)(const RTLIL::Const
&, const RTLIL::Const
&, bool, bool, int);
956 RTLIL::Const dummy_arg
;
961 if (current_scope
.count(str
) > 0 && (current_scope
[str
]->type
== AST_PARAMETER
|| current_scope
[str
]->type
== AST_LOCALPARAM
)) {
962 if (current_scope
[str
]->children
[0]->type
== AST_CONSTANT
) {
963 if (children
.size() != 0 && children
[0]->type
== AST_RANGE
&& children
[0]->range_valid
) {
964 std::vector
<RTLIL::State
> data
;
965 for (int i
= children
[0]->range_right
; i
<= children
[0]->range_left
; i
++)
966 data
.push_back(current_scope
[str
]->children
[0]->bits
[i
]);
967 newNode
= mkconst_bits(data
, false);
969 if (children
.size() == 0)
970 newNode
= current_scope
[str
]->children
[0]->clone();
973 else if (at_zero
&& current_scope
.count(str
) > 0 && (current_scope
[str
]->type
== AST_WIRE
|| current_scope
[str
]->type
== AST_AUTOWIRE
)) {
974 newNode
= mkconst_int(0, sign_hint
, width_hint
);
978 if (children
[0]->type
== AST_CONSTANT
) {
979 RTLIL::Const y
= RTLIL::const_not(children
[0]->bitsAsConst(width_hint
, sign_hint
), dummy_arg
, sign_hint
, false, width_hint
);
980 newNode
= mkconst_bits(y
.bits
, sign_hint
);
983 if (0) { case AST_BIT_AND
: const_func
= RTLIL::const_and
; }
984 if (0) { case AST_BIT_OR
: const_func
= RTLIL::const_or
; }
985 if (0) { case AST_BIT_XOR
: const_func
= RTLIL::const_xor
; }
986 if (0) { case AST_BIT_XNOR
: const_func
= RTLIL::const_xnor
; }
987 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
988 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(width_hint
, sign_hint
),
989 children
[1]->bitsAsConst(width_hint
, sign_hint
), sign_hint
, sign_hint
, width_hint
);
990 newNode
= mkconst_bits(y
.bits
, sign_hint
);
993 if (0) { case AST_REDUCE_AND
: const_func
= RTLIL::const_reduce_and
; }
994 if (0) { case AST_REDUCE_OR
: const_func
= RTLIL::const_reduce_or
; }
995 if (0) { case AST_REDUCE_XOR
: const_func
= RTLIL::const_reduce_xor
; }
996 if (0) { case AST_REDUCE_XNOR
: const_func
= RTLIL::const_reduce_xnor
; }
997 if (0) { case AST_REDUCE_BOOL
: const_func
= RTLIL::const_reduce_bool
; }
998 if (children
[0]->type
== AST_CONSTANT
) {
999 RTLIL::Const y
= const_func(RTLIL::Const(children
[0]->bits
), dummy_arg
, false, false, -1);
1000 newNode
= mkconst_bits(y
.bits
, false);
1004 if (children
[0]->type
== AST_CONSTANT
) {
1005 RTLIL::Const y
= RTLIL::const_logic_not(RTLIL::Const(children
[0]->bits
), dummy_arg
, children
[0]->is_signed
, false, -1);
1006 newNode
= mkconst_bits(y
.bits
, false);
1009 if (0) { case AST_LOGIC_AND
: const_func
= RTLIL::const_logic_and
; }
1010 if (0) { case AST_LOGIC_OR
: const_func
= RTLIL::const_logic_or
; }
1011 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1012 RTLIL::Const y
= const_func(RTLIL::Const(children
[0]->bits
), RTLIL::Const(children
[1]->bits
),
1013 children
[0]->is_signed
, children
[1]->is_signed
, -1);
1014 newNode
= mkconst_bits(y
.bits
, false);
1017 if (0) { case AST_SHIFT_LEFT
: const_func
= RTLIL::const_shl
; }
1018 if (0) { case AST_SHIFT_RIGHT
: const_func
= RTLIL::const_shr
; }
1019 if (0) { case AST_SHIFT_SLEFT
: const_func
= RTLIL::const_sshl
; }
1020 if (0) { case AST_SHIFT_SRIGHT
: const_func
= RTLIL::const_sshr
; }
1021 if (0) { case AST_POW
: const_func
= RTLIL::const_pow
; }
1022 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1023 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(width_hint
, sign_hint
),
1024 RTLIL::Const(children
[1]->bits
), sign_hint
, type
== AST_POW
? children
[1]->is_signed
: false, width_hint
);
1025 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1028 if (0) { case AST_LT
: const_func
= RTLIL::const_lt
; }
1029 if (0) { case AST_LE
: const_func
= RTLIL::const_le
; }
1030 if (0) { case AST_EQ
: const_func
= RTLIL::const_eq
; }
1031 if (0) { case AST_NE
: const_func
= RTLIL::const_ne
; }
1032 if (0) { case AST_GE
: const_func
= RTLIL::const_ge
; }
1033 if (0) { case AST_GT
: const_func
= RTLIL::const_gt
; }
1034 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1035 int cmp_width
= std::max(children
[0]->bits
.size(), children
[1]->bits
.size());
1036 bool cmp_signed
= children
[0]->is_signed
&& children
[1]->is_signed
;
1037 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(cmp_width
, cmp_signed
),
1038 children
[1]->bitsAsConst(cmp_width
, cmp_signed
), cmp_signed
, cmp_signed
, 1);
1039 newNode
= mkconst_bits(y
.bits
, false);
1042 if (0) { case AST_ADD
: const_func
= RTLIL::const_add
; }
1043 if (0) { case AST_SUB
: const_func
= RTLIL::const_sub
; }
1044 if (0) { case AST_MUL
: const_func
= RTLIL::const_mul
; }
1045 if (0) { case AST_DIV
: const_func
= RTLIL::const_div
; }
1046 if (0) { case AST_MOD
: const_func
= RTLIL::const_mod
; }
1047 if (children
[0]->type
== AST_CONSTANT
&& children
[1]->type
== AST_CONSTANT
) {
1048 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(width_hint
, sign_hint
),
1049 children
[1]->bitsAsConst(width_hint
, sign_hint
), sign_hint
, sign_hint
, width_hint
);
1050 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1053 if (0) { case AST_POS
: const_func
= RTLIL::const_pos
; }
1054 if (0) { case AST_NEG
: const_func
= RTLIL::const_neg
; }
1055 if (children
[0]->type
== AST_CONSTANT
) {
1056 RTLIL::Const y
= const_func(children
[0]->bitsAsConst(width_hint
, sign_hint
), dummy_arg
, sign_hint
, false, width_hint
);
1057 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1061 if (children
[0]->type
== AST_CONSTANT
) {
1062 bool found_sure_true
= false;
1063 bool found_maybe_true
= false;
1064 for (auto &bit
: children
[0]->bits
) {
1065 if (bit
== RTLIL::State::S1
)
1066 found_sure_true
= true;
1067 if (bit
> RTLIL::State::S1
)
1068 found_maybe_true
= true;
1070 AstNode
*choice
= NULL
;
1071 if (found_sure_true
)
1072 choice
= children
[1];
1073 else if (!found_maybe_true
)
1074 choice
= children
[2];
1075 if (choice
!= NULL
&& choice
->type
== AST_CONSTANT
) {
1076 RTLIL::Const y
= choice
->bitsAsConst(width_hint
, sign_hint
);
1077 newNode
= mkconst_bits(y
.bits
, sign_hint
);
1078 } else if (children
[1]->type
== AST_CONSTANT
&& children
[2]->type
== AST_CONSTANT
) {
1079 RTLIL::Const a
= children
[1]->bitsAsConst(width_hint
, sign_hint
);
1080 RTLIL::Const b
= children
[2]->bitsAsConst(width_hint
, sign_hint
);
1081 assert(a
.bits
.size() == b
.bits
.size());
1082 for (size_t i
= 0; i
< a
.bits
.size(); i
++)
1083 if (a
.bits
[i
] != b
.bits
[i
])
1084 a
.bits
[i
] = RTLIL::State::Sx
;
1085 newNode
= mkconst_bits(a
.bits
, sign_hint
);
1090 for (auto it
= children
.begin(); it
!= children
.end(); it
++) {
1091 if ((*it
)->type
!= AST_CONSTANT
)
1093 tmp_bits
.insert(tmp_bits
.end(), (*it
)->bits
.begin(), (*it
)->bits
.end());
1095 newNode
= mkconst_bits(tmp_bits
, false);
1098 if (children
.at(0)->type
!= AST_CONSTANT
|| children
.at(1)->type
!= AST_CONSTANT
)
1100 for (int i
= 0; i
< children
[0]->bitsAsConst().as_int(); i
++)
1101 tmp_bits
.insert(tmp_bits
.end(), children
.at(1)->bits
.begin(), children
.at(1)->bits
.end());
1102 newNode
= mkconst_bits(tmp_bits
, false);
1110 // if any of the above set 'newNode' -> use 'newNode' as template to update 'this'
1113 // fprintf(stderr, "----\n");
1114 // dumpAst(stderr, "- ");
1115 // newNode->dumpAst(stderr, "+ ");
1116 assert(newNode
!= NULL
);
1117 newNode
->filename
= filename
;
1118 newNode
->linenum
= linenum
;
1119 newNode
->cloneInto(this);
1121 did_something
= true;
1124 return did_something
;
1127 // annotate the names of all wires and other named objects in a generate block
1128 void AstNode::expand_genblock(std::string index_var
, std::string prefix
, std::map
<std::string
, std::string
> &name_map
)
1130 if (!index_var
.empty() && type
== AST_IDENTIFIER
&& str
== index_var
) {
1131 current_scope
[index_var
]->children
[0]->cloneInto(this);
1135 if ((type
== AST_IDENTIFIER
|| type
== AST_FCALL
|| type
== AST_TCALL
) && name_map
.count(str
) > 0)
1136 str
= name_map
[str
];
1138 std::map
<std::string
, std::string
> backup_name_map
;
1140 for (size_t i
= 0; i
< children
.size(); i
++) {
1141 AstNode
*child
= children
[i
];
1142 if (child
->type
== AST_WIRE
|| child
->type
== AST_MEMORY
|| child
->type
== AST_PARAMETER
|| child
->type
== AST_LOCALPARAM
||
1143 child
->type
== AST_FUNCTION
|| child
->type
== AST_TASK
|| child
->type
== AST_CELL
) {
1144 if (backup_name_map
.size() == 0)
1145 backup_name_map
= name_map
;
1146 std::string new_name
= prefix
[0] == '\\' ? prefix
.substr(1) : prefix
;
1147 size_t pos
= child
->str
.rfind('.');
1148 if (pos
== std::string::npos
)
1149 pos
= child
->str
[0] == '\\' ? 1 : 0;
1152 new_name
= child
->str
.substr(0, pos
) + new_name
+ child
->str
.substr(pos
);
1153 if (new_name
[0] != '$' && new_name
[0] != '\\')
1154 new_name
= prefix
[0] + new_name
;
1155 name_map
[child
->str
] = new_name
;
1156 child
->str
= new_name
;
1160 for (size_t i
= 0; i
< children
.size(); i
++) {
1161 AstNode
*child
= children
[i
];
1162 if (child
->type
!= AST_FUNCTION
&& child
->type
!= AST_TASK
)
1163 child
->expand_genblock(index_var
, prefix
, name_map
);
1166 if (backup_name_map
.size() > 0)
1167 name_map
.swap(backup_name_map
);
1170 // rename stuff (used when tasks of functions are instanciated)
1171 void AstNode::replace_ids(std::map
<std::string
, std::string
> &rules
)
1173 if (type
== AST_IDENTIFIER
&& rules
.count(str
) > 0)
1175 for (auto child
: children
)
1176 child
->replace_ids(rules
);
1179 // find memories that should be replaced by registers
1180 void AstNode::mem2reg_as_needed_pass1(std::set
<AstNode
*> &mem2reg_set
, std::set
<AstNode
*> &mem2reg_candidates
, bool sync_proc
, bool async_proc
, bool force_mem2reg
)
1182 if ((type
== AST_ASSIGN_LE
&& async_proc
) || (type
== AST_ASSIGN_EQ
&& (sync_proc
|| async_proc
)))
1183 if (children
[0]->type
== AST_IDENTIFIER
&& children
[0]->id2ast
&& children
[0]->id2ast
->type
== AST_MEMORY
&&
1184 !children
[0]->id2ast
->get_bool_attribute("\\nomem2reg")) {
1185 if (async_proc
|| mem2reg_candidates
.count(children
[0]->id2ast
) > 0) {
1186 if (mem2reg_set
.count(children
[0]->id2ast
) == 0)
1187 log("Warning: Replacing memory %s with list of registers because of assignment in line %s:%d.\n",
1188 children
[0]->str
.c_str(), filename
.c_str(), linenum
);
1189 mem2reg_set
.insert(children
[0]->id2ast
);
1191 mem2reg_candidates
.insert(children
[0]->id2ast
);
1194 if (type
== AST_MEMORY
&& (get_bool_attribute("\\mem2reg") || force_mem2reg
))
1195 mem2reg_set
.insert(this);
1197 if (type
== AST_MODULE
&& get_bool_attribute("\\mem2reg"))
1198 force_mem2reg
= true;
1200 if (type
== AST_ALWAYS
) {
1201 for (auto child
: children
) {
1202 if (child
->type
== AST_POSEDGE
|| child
->type
== AST_NEGEDGE
)
1205 async_proc
= !sync_proc
;
1208 for (auto child
: children
)
1209 child
->mem2reg_as_needed_pass1(mem2reg_set
, mem2reg_candidates
, sync_proc
, async_proc
, force_mem2reg
);
1212 // actually replace memories with registers
1213 void AstNode::mem2reg_as_needed_pass2(std::set
<AstNode
*> &mem2reg_set
, AstNode
*mod
, AstNode
*block
)
1215 if (type
== AST_BLOCK
)
1218 if ((type
== AST_ASSIGN_LE
|| type
== AST_ASSIGN_EQ
) && block
!= NULL
&&
1219 children
[0]->id2ast
&& mem2reg_set
.count(children
[0]->id2ast
) > 0)
1221 std::stringstream sstr
;
1222 sstr
<< "$mem2reg_wr$" << children
[0]->str
<< "$" << filename
<< ":" << linenum
<< "$" << (RTLIL::autoidx
++);
1223 std::string id_addr
= sstr
.str() + "_ADDR", id_data
= sstr
.str() + "_DATA";
1225 int mem_width
, mem_size
, addr_bits
;
1226 children
[0]->id2ast
->meminfo(mem_width
, mem_size
, addr_bits
);
1228 AstNode
*wire_addr
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(addr_bits
-1, true), mkconst_int(0, true)));
1229 wire_addr
->str
= id_addr
;
1230 wire_addr
->is_reg
= true;
1231 wire_addr
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
1232 mod
->children
.push_back(wire_addr
);
1233 while (wire_addr
->simplify(true, false, false, 1, -1, false)) { }
1235 AstNode
*wire_data
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
1236 wire_data
->str
= id_data
;
1237 wire_data
->is_reg
= true;
1238 wire_data
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
1239 mod
->children
.push_back(wire_data
);
1240 while (wire_data
->simplify(true, false, false, 1, -1, false)) { }
1242 assert(block
!= NULL
);
1243 size_t assign_idx
= 0;
1244 while (assign_idx
< block
->children
.size() && block
->children
[assign_idx
] != this)
1246 assert(assign_idx
< block
->children
.size());
1248 AstNode
*assign_addr
= new AstNode(AST_ASSIGN_EQ
, new AstNode(AST_IDENTIFIER
), children
[0]->children
[0]->children
[0]->clone());
1249 assign_addr
->children
[0]->str
= id_addr
;
1250 block
->children
.insert(block
->children
.begin()+assign_idx
+1, assign_addr
);
1252 AstNode
*case_node
= new AstNode(AST_CASE
, new AstNode(AST_IDENTIFIER
));
1253 case_node
->children
[0]->str
= id_addr
;
1254 for (int i
= 0; i
< mem_size
; i
++) {
1255 if (children
[0]->children
[0]->children
[0]->type
== AST_CONSTANT
&& int(children
[0]->children
[0]->children
[0]->integer
) != i
)
1257 AstNode
*cond_node
= new AstNode(AST_COND
, AstNode::mkconst_int(i
, false, addr_bits
), new AstNode(AST_BLOCK
));
1258 AstNode
*assign_reg
= new AstNode(type
, new AstNode(AST_IDENTIFIER
), new AstNode(AST_IDENTIFIER
));
1259 assign_reg
->children
[0]->str
= stringf("%s[%d]", children
[0]->str
.c_str(), i
);
1260 assign_reg
->children
[1]->str
= id_data
;
1261 cond_node
->children
[1]->children
.push_back(assign_reg
);
1262 case_node
->children
.push_back(cond_node
);
1264 block
->children
.insert(block
->children
.begin()+assign_idx
+2, case_node
);
1266 children
[0]->delete_children();
1267 children
[0]->range_valid
= false;
1268 children
[0]->id2ast
= NULL
;
1269 children
[0]->str
= id_data
;
1270 type
= AST_ASSIGN_EQ
;
1273 if (type
== AST_IDENTIFIER
&& id2ast
&& mem2reg_set
.count(id2ast
) > 0)
1275 std::stringstream sstr
;
1276 sstr
<< "$mem2reg_rd$" << children
[0]->str
<< "$" << filename
<< ":" << linenum
<< "$" << (RTLIL::autoidx
++);
1277 std::string id_addr
= sstr
.str() + "_ADDR", id_data
= sstr
.str() + "_DATA";
1279 int mem_width
, mem_size
, addr_bits
;
1280 id2ast
->meminfo(mem_width
, mem_size
, addr_bits
);
1282 AstNode
*wire_addr
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(addr_bits
-1, true), mkconst_int(0, true)));
1283 wire_addr
->str
= id_addr
;
1285 wire_addr
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
1286 mod
->children
.push_back(wire_addr
);
1287 while (wire_addr
->simplify(true, false, false, 1, -1, false)) { }
1289 AstNode
*wire_data
= new AstNode(AST_WIRE
, new AstNode(AST_RANGE
, mkconst_int(mem_width
-1, true), mkconst_int(0, true)));
1290 wire_data
->str
= id_data
;
1292 wire_data
->attributes
["\\nosync"] = AstNode::mkconst_int(1, false);
1293 mod
->children
.push_back(wire_data
);
1294 while (wire_data
->simplify(true, false, false, 1, -1, false)) { }
1296 AstNode
*assign_addr
= new AstNode(block
? AST_ASSIGN_EQ
: AST_ASSIGN
, new AstNode(AST_IDENTIFIER
), children
[0]->children
[0]->clone());
1297 assign_addr
->children
[0]->str
= id_addr
;
1299 AstNode
*case_node
= new AstNode(AST_CASE
, new AstNode(AST_IDENTIFIER
));
1300 case_node
->children
[0]->str
= id_addr
;
1302 for (int i
= 0; i
< mem_size
; i
++) {
1303 if (children
[0]->children
[0]->type
== AST_CONSTANT
&& int(children
[0]->children
[0]->integer
) != i
)
1305 AstNode
*cond_node
= new AstNode(AST_COND
, AstNode::mkconst_int(i
, false, addr_bits
), new AstNode(AST_BLOCK
));
1306 AstNode
*assign_reg
= new AstNode(AST_ASSIGN_EQ
, new AstNode(AST_IDENTIFIER
), new AstNode(AST_IDENTIFIER
));
1307 assign_reg
->children
[0]->str
= id_data
;
1308 assign_reg
->children
[1]->str
= stringf("%s[%d]", str
.c_str(), i
);
1309 cond_node
->children
[1]->children
.push_back(assign_reg
);
1310 case_node
->children
.push_back(cond_node
);
1313 std::vector
<RTLIL::State
> x_bits
;
1314 for (int i
= 0; i
< mem_width
; i
++)
1315 x_bits
.push_back(RTLIL::State::Sx
);
1317 AstNode
*cond_node
= new AstNode(AST_COND
, new AstNode(AST_DEFAULT
), new AstNode(AST_BLOCK
));
1318 AstNode
*assign_reg
= new AstNode(AST_ASSIGN_EQ
, new AstNode(AST_IDENTIFIER
), AstNode::mkconst_bits(x_bits
, false));
1319 assign_reg
->children
[0]->str
= id_data
;
1320 cond_node
->children
[1]->children
.push_back(assign_reg
);
1321 case_node
->children
.push_back(cond_node
);
1325 size_t assign_idx
= 0;
1326 while (assign_idx
< block
->children
.size() && !block
->children
[assign_idx
]->contains(this))
1328 assert(assign_idx
< block
->children
.size());
1329 block
->children
.insert(block
->children
.begin()+assign_idx
, case_node
);
1330 block
->children
.insert(block
->children
.begin()+assign_idx
, assign_addr
);
1331 wire_addr
->is_reg
= true;
1332 wire_data
->is_reg
= true;
1336 AstNode
*proc
= new AstNode(AST_ALWAYS
, new AstNode(AST_BLOCK
));
1337 proc
->children
[0]->children
.push_back(case_node
);
1338 mod
->children
.push_back(proc
);
1339 mod
->children
.push_back(assign_addr
);
1343 range_valid
= false;
1348 assert(id2ast
== NULL
|| mem2reg_set
.count(id2ast
) == 0);
1350 auto children_list
= children
;
1351 for (size_t i
= 0; i
< children_list
.size(); i
++)
1352 children_list
[i
]->mem2reg_as_needed_pass2(mem2reg_set
, mod
, block
);
1355 // calulate memory dimensions
1356 void AstNode::meminfo(int &mem_width
, int &mem_size
, int &addr_bits
)
1358 assert(type
== AST_MEMORY
);
1360 mem_width
= children
[0]->range_left
- children
[0]->range_right
+ 1;
1361 mem_size
= children
[1]->range_left
- children
[1]->range_right
;
1365 mem_size
+= std::min(children
[1]->range_left
, children
[1]->range_right
) + 1;
1368 while ((1 << addr_bits
) < mem_size
)