56 log(
"-------------\n");
57 log(
"const_fold=%d, at_zero=%d, in_lvalue=%d, stage=%d, width_hint=%d, sign_hint=%d, in_param=%d\n",
58 int(const_fold),
int(at_zero),
int(in_lvalue),
int(stage),
int(width_hint),
int(sign_hint),
int(in_param));
66 while (
simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint, in_param)) { }
70 std::map<AstNode*, std::set<std::string>> mem2reg_places;
71 std::map<AstNode*, uint32_t> mem2reg_candidates, dummy_proc_flags;
75 std::set<AstNode*> mem2reg_set;
76 for (
auto &it : mem2reg_candidates)
79 uint32_t memflags = it.second;
89 goto verbose_activate;
92 goto verbose_activate;
95 goto verbose_activate;
98 goto verbose_activate;
104 if (mem2reg_set.count(mem) == 0) {
105 log_warning(
"Replacing memory %s with list of registers.", mem->
str.c_str());
106 bool first_element =
true;
107 for (
auto &place : mem2reg_places[it.first]) {
108 log(
"%s%s", first_element ?
" See " :
", ", place.c_str());
109 first_element =
false;
116 mem2reg_set.insert(mem);
119 for (
auto node : mem2reg_set)
121 int mem_width, mem_size, addr_bits;
122 node->meminfo(mem_width, mem_size, addr_bits);
124 for (
int i = 0; i < mem_size; i++) {
127 reg->
str =
stringf(
"%s[%d]", node->str.c_str(), i);
131 while (reg->
simplify(
true,
false,
false, 1, -1,
false,
false)) { }
137 for (
size_t i = 0; i <
children.size(); i++) {
138 if (mem2reg_set.count(
children[i]) > 0) {
145 while (
simplify(const_fold, at_zero, in_lvalue, 2, width_hint, sign_hint, in_param)) { }
173 std::map<std::string, AstNode*> backup_scope;
179 std::map<std::string, AstNode*> this_wire_scope;
180 for (
size_t i = 0; i <
children.size(); i++) {
183 if (this_wire_scope.count(node->
str) > 0) {
184 AstNode *first_node = this_wire_scope[node->
str];
186 goto wires_are_compatible;
188 goto wires_are_incompatible;
189 for (
size_t j = 0; j < node->
children.size(); j++) {
193 goto wires_are_incompatible;
195 goto wires_are_incompatible;
196 }
else if (*n1 != *n2)
197 goto wires_are_incompatible;
200 goto wires_are_incompatible;
202 goto wires_are_incompatible;
204 goto wires_are_incompatible;
205 wires_are_compatible:
211 first_node->
is_reg =
true;
215 if (first_node->
attributes.count(it.first) > 0)
217 first_node->
attributes[it.first] = it.second->clone();
220 did_something =
true;
223 wires_are_incompatible:
228 this_wire_scope[node->
str] = node;
236 for (
size_t i = 0; i <
children.size(); i++) {
240 did_something =
true;
248 int backup_width_hint = width_hint;
249 bool backup_sign_hint = sign_hint;
251 bool detect_width_simple =
false;
252 bool child_0_is_self_determined =
false;
253 bool child_1_is_self_determined =
false;
254 bool child_2_is_self_determined =
false;
255 bool children_are_self_determined =
false;
256 bool reset_width_after_children =
false;
264 did_something =
true;
266 did_something =
true;
267 children[0]->detectSignWidth(backup_width_hint, backup_sign_hint);
268 children[1]->detectSignWidth(width_hint, sign_hint);
269 width_hint = std::max(width_hint, backup_width_hint);
270 child_0_is_self_determined =
true;
276 did_something =
true;
277 children[0]->detectSignWidth(width_hint, sign_hint);
280 did_something =
true;
297 detect_width_simple =
true;
298 children_are_self_determined =
true;
313 detect_width_simple =
true;
321 detect_width_simple =
true;
322 child_1_is_self_determined =
true;
336 while (!child->basic_prep && child->simplify(
false,
false, in_lvalue, stage, -1,
false, in_param) ==
true)
337 did_something =
true;
338 child->detectSignWidthWorker(width_hint, sign_hint);
340 reset_width_after_children =
true;
346 detect_width_simple =
true;
347 children_are_self_determined =
true;
351 detect_width_simple =
true;
352 child_0_is_self_determined =
true;
356 detect_width_simple =
true;
357 children_are_self_determined =
true;
365 if (detect_width_simple && width_hint < 0) {
367 while (children[0]->
simplify(
true,
false, in_lvalue, stage, -1,
false,
true) ==
true)
368 did_something =
true;
369 for (
auto child : children)
370 while (!child->basic_prep && child->simplify(
false,
false, in_lvalue, stage, -1,
false, in_param) ==
true)
371 did_something =
true;
376 int width_hint_left, width_hint_right;
377 bool sign_hint_left, sign_hint_right;
378 bool found_real_left, found_real_right;
379 children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left);
380 children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right);
381 if (found_real_left || found_real_right) {
382 child_1_is_self_determined =
true;
383 child_2_is_self_determined =
true;
389 while (children[0]->
simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { }
391 std::vector<AstNode*> new_children;
392 new_children.push_back(children[0]);
393 for (
int i = 1; i <
GetSize(children); i++) {
398 goto keep_const_cond;
401 while (v->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { }
403 if (v->bits == children[0]->bits) {
404 while (i+1 <
GetSize(children))
405 delete children[++i];
406 goto keep_const_cond;
410 goto keep_const_cond;
414 new_children.push_back(child);
418 new_children.swap(children);
424 for (
size_t i = 0; i < children.size(); i++) {
425 bool did_something_here =
true;
436 while (did_something_here && i < children.size()) {
437 bool const_fold_here = const_fold, in_lvalue_here = in_lvalue;
438 int width_hint_here = width_hint;
439 bool sign_hint_here = sign_hint;
440 bool in_param_here = in_param;
442 const_fold_here =
true, in_param_here =
true;
444 const_fold_here =
true;
446 in_lvalue_here =
true;
453 if (i == 0 && child_0_is_self_determined)
454 width_hint_here = -1, sign_hint_here =
false;
455 if (i == 1 && child_1_is_self_determined)
456 width_hint_here = -1, sign_hint_here =
false;
457 if (i == 2 && child_2_is_self_determined)
458 width_hint_here = -1, sign_hint_here =
false;
459 if (children_are_self_determined)
460 width_hint_here = -1, sign_hint_here =
false;
461 did_something_here = children[i]->
simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param_here);
462 if (did_something_here)
463 did_something =
true;
467 children.erase(children.begin() + (i--));
468 did_something =
true;
472 while (attr.second->simplify(
true,
false,
false, stage, -1,
false,
true))
473 did_something =
true;
476 if (reset_width_after_children) {
477 width_hint = backup_width_hint;
478 sign_hint = backup_sign_hint;
487 for (
auto it = backup_scope.begin(); it != backup_scope.end(); it++) {
488 if (it->second ==
NULL)
502 size_t pos =
str.rfind(
'.');
503 if (pos == std::string::npos)
504 log_error(
"Defparam `%s' does not contain a dot (module/parameter separator) at %s:%d!\n",
506 std::string modname =
str.substr(0, pos), paraname =
"\\" +
str.substr(pos+1);
512 paraset->str = paraname;
523 newNode = children[1]->
clone();
524 const char *second_part = children[1]->
str.c_str();
525 if (second_part[0] ==
'\\')
527 newNode->
str =
stringf(
"%s[%d].%s",
str.c_str(), children[0]->integer, second_part);
538 newNode =
mkconst_bits(new_value.bits, children[1]->is_signed);
553 if (children.size() == 1)
556 if (children.size() >= 2) {
563 did_something =
true;
574 if (children.size() > 0) {
577 did_something =
true;
585 did_something =
true;
598 for (
auto range : children[1]->children) {
599 if (!range->range_valid)
602 multirange_dimensions.push_back(std::max(range->range_left, range->range_right) - std::min(range->range_left, range->range_right) + 1);
607 did_something =
true;
617 if (
GetSize(children[0]->children) < i)
620 AstNode *new_index_expr = children[0]->
children[i]->children.at(0)->clone();
626 index_expr = new_index_expr;
632 children.push_back(children[0]->children[i]->clone());
635 if (index_expr ==
nullptr)
636 children.erase(children.begin());
640 did_something =
true;
645 if (children.size() > 1 && children[1]->type ==
AST_RANGE) {
648 int width = children[1]->range_left - children[1]->range_right + 1;
650 RTLIL::Const constvalue = children[0]->realAsConst(width);
651 log_warning(
"converting real value %e to binary %s at %s:%d.\n",
655 did_something =
true;
658 if (width !=
int(children[0]->
bits.size())) {
660 sig.extend_u0(width, children[0]->
is_signed);
661 AstNode *old_child_0 = children[0];
662 children[0] =
mkconst_bits(sig.as_const().bits, children[0]->is_signed);
673 double as_realvalue = children[0]->asReal(sign_hint);
676 children[0]->realvalue = as_realvalue;
677 did_something =
true;
698 did_something =
true;
702 did_something =
true;
712 int mem_width, mem_size, addr_bits;
715 std::stringstream sstr;
717 std::string wire_id = sstr.str();
724 while (wire->
simplify(
true,
false,
false, 1, -1,
false,
false)) { }
735 size_t assign_idx = 0;
738 log_assert(assign_idx < current_block->children.size());
745 proc->
children[0]->children.push_back(assign);
750 newNode->
str = wire_id;
764 AstNode *init_ast = children[0];
765 AstNode *while_ast = children[1];
766 AstNode *next_ast = children[2];
767 AstNode *body_ast = children[3];
771 body_ast = body_ast->
children.at(0);
780 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);
782 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);
785 log_error(
"Left hand side of 1st expression of generate for-loop at %s:%d is not a register!\n",
filename.c_str(),
linenum);
787 log_error(
"Left hand side of 3rd expression of generate for-loop at %s:%d is not a register!\n",
filename.c_str(),
linenum);
791 log_error(
"Incompatible left-hand sides in 1st and 3rd expression of generate for-loop at %s:%d!\n",
filename.c_str(),
linenum);
795 while (varbuf->simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
798 log_error(
"Right hand side of 1st expression of generate for-loop at %s:%d is not constant!\n",
filename.c_str(),
linenum);
801 varbuf->str = init_ast->
children[0]->str;
806 size_t current_block_idx = 0;
808 while (current_block_idx < current_block->children.size() &&
817 while (buf->
simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
829 int index = varbuf->
children[0]->integer;
831 buf = body_ast->
clone();
834 if (buf->
str.empty()) {
835 std::stringstream sstr;
837 buf->
str = sstr.str();
839 std::map<std::string, std::string> name_map;
840 std::stringstream sstr;
841 sstr << buf->
str <<
"[" << index <<
"].";
845 for (
size_t i = 0; i < buf->
children.size(); i++) {
846 buf->
children[i]->simplify(
false,
false,
false, stage, -1,
false,
false);
850 for (
size_t i = 0; i < buf->
children.size(); i++)
857 buf = next_ast->
children[1]->clone();
858 while (buf->
simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
861 log_error(
"Right hand side of 3rd expression of generate for-loop at %s:%d is not constant!\n",
filename.c_str(),
linenum);
863 delete varbuf->children[0];
864 varbuf->children[0] = buf;
870 did_something =
true;
876 std::map<std::string, std::string> name_map;
879 std::vector<AstNode*> new_children;
880 for (
size_t i = 0; i < children.size(); i++)
882 children[i]->simplify(
false,
false,
false, stage, -1,
false,
false);
886 new_children.push_back(children[i]);
888 children.swap(new_children);
889 did_something =
true;
897 std::map<std::string, std::string> name_map;
901 for (
size_t i = 0; i < children.size(); i++) {
902 children[i]->simplify(
false,
false,
false, stage, -1,
false,
false);
907 did_something =
true;
914 while (buf->
simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
922 buf = children[1]->
clone();
925 buf = children.size() > 2 ? children[2]->
clone() :
NULL;
933 if (!buf->
str.empty()) {
934 std::map<std::string, std::string> name_map;
938 for (
size_t i = 0; i < buf->
children.size(); i++) {
939 buf->
children[i]->simplify(
false,
false,
false, stage, -1,
false,
false);
948 did_something =
true;
955 while (buf->
simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
967 for (
size_t i = 1; i < children.size(); i++)
972 for (
auto child : children.at(i)->
children) {
975 this_genblock = child;
978 for (
auto child : children.at(i)->
children)
981 if (selected_case ==
NULL)
982 selected_case = this_genblock;
988 buf = child->
clone();
989 while (buf->
simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
1000 selected_case = this_genblock;
1001 i = children.size();
1007 if (selected_case !=
NULL)
1010 buf = selected_case->
clone();
1012 if (!buf->
str.empty()) {
1013 std::map<std::string, std::string> name_map;
1017 for (
size_t i = 0; i < buf->
children.size(); i++) {
1018 buf->
children[i]->simplify(
false,
false,
false, stage, -1,
false,
false);
1027 did_something =
true;
1033 if (!children.at(0)->range_valid)
1037 int num = std::max(children.at(0)->range_left, children.at(0)->range_right) - std::min(children.at(0)->range_left, children.at(0)->range_right) + 1;
1039 for (
int i = 0; i < num; i++) {
1040 int idx = children.at(0)->range_left > children.at(0)->range_right ? children.at(0)->range_right + i : children.at(0)->range_right - i;
1042 newNode->
children.push_back(new_cell);
1058 if (children.size() < 2)
1059 log_error(
"Insufficient number of arguments for primitive `%s' at %s:%d!\n",
1062 std::vector<AstNode*> children_list;
1063 for (
auto child : children) {
1066 children_list.push_back(child->
children[0]);
1072 if (
str ==
"bufif0" ||
str ==
"bufif1" ||
str ==
"notif0" ||
str ==
"notif1")
1074 if (children_list.size() != 3)
1075 log_error(
"Invalid number of arguments for primitive `%s' at %s:%d!\n",
1080 AstNode *mux_input = children_list.at(1);
1081 if (
str ==
"notif0" ||
str ==
"notif1") {
1085 if (
str ==
"bufif0") {
1087 node->
children.push_back(mux_input);
1089 node->
children.push_back(mux_input);
1095 children.push_back(children_list.at(0));
1096 children.push_back(node);
1097 did_something =
true;
1102 bool invert_results =
false;
1119 op_type =
AST_POS, invert_results =
true;
1122 AstNode *node = children_list[1];
1124 for (
size_t i = 2; i < children_list.size(); i++)
1125 node =
new AstNode(op_type, node, children_list[i]);
1131 children.push_back(children_list[0]);
1132 children.push_back(node);
1133 did_something =
true;
1141 goto skip_dynamic_range_lvalue_expansion;
1142 if (children[0]->children[0]->
range_valid || did_something)
1143 goto skip_dynamic_range_lvalue_expansion;
1145 goto skip_dynamic_range_lvalue_expansion;
1147 goto skip_dynamic_range_lvalue_expansion;
1148 int source_width = children[0]->id2ast->range_left - children[0]->id2ast->range_right + 1;
1149 int result_width = 1;
1153 shift_expr = range->
children[0]->clone();
1155 shift_expr = range->
children[1]->clone();
1158 while (left_at_zero_ast->
simplify(
true,
true,
false, stage, -1,
false,
false)) { }
1159 while (right_at_zero_ast->
simplify(
true,
true,
false, stage, -1,
false,
false)) { }
1161 log_error(
"Unsupported expression on dynamic range select on signal `%s' at %s:%d!\n",
1163 result_width = abs(
int(left_at_zero_ast->
integer - right_at_zero_ast->
integer)) + 1;
1165 did_something =
true;
1167 for (
int i = 0; i <= source_width-result_width; i++) {
1168 int start_bit = children[0]->id2ast->range_right + i;
1179 skip_dynamic_range_lvalue_expansion:;
1183 std::stringstream sstr;
1185 std::string id_check = sstr.str() +
"_CHECK", id_en = sstr.str() +
"_EN";
1188 wire_check->
str = id_check;
1191 while (wire_check->
simplify(
true,
false,
false, 1, -1,
false,
false)) { }
1194 wire_en->
str = id_en;
1199 while (wire_en->
simplify(
true,
false,
false, 1, -1,
false,
false)) { }
1201 std::vector<RTLIL::State> x_bit;
1205 assign_check->
children[0]->str = id_check;
1208 assign_en->
children[0]->str = id_en;
1211 default_signals->
children.push_back(assign_check);
1212 default_signals->
children.push_back(assign_en);
1216 assign_check->
children[0]->str = id_check;
1219 assign_en->
children[0]->str = id_en;
1222 newNode->
children.push_back(assign_check);
1223 newNode->
children.push_back(assign_en);
1228 assertnode->
children[0]->str = id_check;
1229 assertnode->
children[1]->str = id_en;
1240 did_something =
true;
1245 children[0]->type ==
AST_RANGE && children[0]->children.size() == 1) {
1255 children[0]->id2ast->children[0]->range_valid && children[0]->id2ast->children[1]->range_valid &&
1256 (children[0]->children.size() == 1 || children[0]->children.size() == 2) && children[0]->children[0]->
type ==
AST_RANGE)
1258 std::stringstream sstr;
1260 std::string id_addr = sstr.str() +
"_ADDR", id_data = sstr.str() +
"_DATA", id_en = sstr.str() +
"_EN";
1263 log_warning(
"Blocking assignment to memory in line %s:%d is handled like a non-blocking assignment.\n",
1266 int mem_width, mem_size, addr_bits;
1267 children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
1270 wire_addr->
str = id_addr;
1273 while (wire_addr->
simplify(
true,
false,
false, 1, -1,
false,
false)) { }
1276 wire_data->
str = id_data;
1279 while (wire_data->
simplify(
true,
false,
false, 1, -1,
false,
false)) { }
1282 wire_en->
str = id_en;
1285 while (wire_en->
simplify(
true,
false,
false, 1, -1,
false,
false)) { }
1287 std::vector<RTLIL::State> x_bits_addr, x_bits_data, set_bits_en;
1288 for (
int i = 0; i < addr_bits; i++)
1290 for (
int i = 0; i < mem_width; i++)
1292 for (
int i = 0; i < mem_width; i++)
1296 assign_addr->
children[0]->str = id_addr;
1299 assign_data->
children[0]->str = id_data;
1302 assign_en->
children[0]->str = id_en;
1305 default_signals->
children.push_back(assign_addr);
1306 default_signals->
children.push_back(assign_data);
1307 default_signals->
children.push_back(assign_en);
1311 assign_addr->
children[0]->str = id_addr;
1313 if (children[0]->children.size() == 2)
1317 int offset = children[0]->children[1]->range_right;
1318 int width = children[0]->children[1]->range_left - offset + 1;
1322 for (
int i = 0; i < mem_width; i++)
1327 assign_data->
children[0]->str = id_data;
1330 assign_en->
children[0]->str = id_en;
1339 while (left_at_zero_ast->
simplify(
true,
true,
false, 1, -1,
false,
false)) { }
1340 while (right_at_zero_ast->
simplify(
true,
true,
false, 1, -1,
false,
false)) { }
1343 int width = left_at_zero_ast->
integer - right_at_zero_ast->
integer + 1;
1345 for (
int i = 0; i < mem_width; i++)
1350 assign_data->
children[0]->str = id_data;
1354 assign_en->
children[0]->str = id_en;
1356 delete left_at_zero_ast;
1357 delete right_at_zero_ast;
1364 assign_data->
children[0]->str = id_data;
1367 assign_en->
children[0]->str = id_en;
1371 newNode->
children.push_back(assign_addr);
1372 newNode->
children.push_back(assign_data);
1373 newNode->
children.push_back(assign_en);
1379 wrnode->
str = children[0]->str;
1380 wrnode->
children[0]->str = id_addr;
1381 wrnode->
children[1]->str = id_data;
1393 if (
str ==
"\\$clog2")
1395 if (children.size() != 1)
1396 log_error(
"System function %s got %d arguments, expected 1 at %s:%d.\n",
1400 while (buf->
simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
1405 if (arg_value.as_bool())
1409 uint32_t result = 0;
1410 for (
size_t i = 0; i < arg_value.bits.size(); i++)
1418 if (
str ==
"\\$ln" ||
str ==
"\\$log10" ||
str ==
"\\$exp" ||
str ==
"\\$sqrt" ||
str ==
"\\$pow" ||
1419 str ==
"\\$floor" ||
str ==
"\\$ceil" ||
str ==
"\\$sin" ||
str ==
"\\$cos" ||
str ==
"\\$tan" ||
1420 str ==
"\\$asin" ||
str ==
"\\$acos" ||
str ==
"\\$atan" ||
str ==
"\\$atan2" ||
str ==
"\\$hypot" ||
1421 str ==
"\\$sinh" ||
str ==
"\\$cosh" ||
str ==
"\\$tanh" ||
str ==
"\\$asinh" ||
str ==
"\\$acosh" ||
str ==
"\\$atanh")
1423 bool func_with_two_arguments =
str ==
"\\$pow" ||
str ==
"\\$atan2" ||
str ==
"\\$hypot";
1424 double x = 0, y = 0;
1426 if (func_with_two_arguments) {
1427 if (children.size() != 2)
1428 log_error(
"System function %s got %d arguments, expected 2 at %s:%d.\n",
1431 if (children.size() != 1)
1432 log_error(
"System function %s got %d arguments, expected 1 at %s:%d.\n",
1436 if (children.size() >= 1) {
1437 while (children[0]->
simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
1439 log_error(
"Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n",
1441 int child_width_hint = width_hint;
1442 bool child_sign_hint = sign_hint;
1443 children[0]->detectSignWidth(child_width_hint, child_sign_hint);
1444 x = children[0]->asReal(child_sign_hint);
1447 if (children.size() >= 2) {
1448 while (children[1]->
simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
1450 log_error(
"Failed to evaluate system function `%s' with non-constant argument at %s:%d.\n",
1452 int child_width_hint = width_hint;
1453 bool child_sign_hint = sign_hint;
1454 children[1]->detectSignWidth(child_width_hint, child_sign_hint);
1455 y = children[1]->asReal(child_sign_hint);
1460 else if (
str ==
"\\$log10") newNode->
realvalue = ::log10(x);
1461 else if (
str ==
"\\$exp") newNode->
realvalue = ::exp(x);
1462 else if (
str ==
"\\$sqrt") newNode->
realvalue = ::sqrt(x);
1463 else if (
str ==
"\\$pow") newNode->
realvalue = ::pow(x, y);
1464 else if (
str ==
"\\$floor") newNode->
realvalue = ::floor(x);
1465 else if (
str ==
"\\$ceil") newNode->
realvalue = ::ceil(x);
1466 else if (
str ==
"\\$sin") newNode->
realvalue = ::sin(x);
1467 else if (
str ==
"\\$cos") newNode->
realvalue = ::cos(x);
1468 else if (
str ==
"\\$tan") newNode->
realvalue = ::tan(x);
1469 else if (
str ==
"\\$asin") newNode->
realvalue = ::asin(x);
1470 else if (
str ==
"\\$acos") newNode->
realvalue = ::acos(x);
1471 else if (
str ==
"\\$atan") newNode->
realvalue = ::atan(x);
1472 else if (
str ==
"\\$atan2") newNode->
realvalue = ::atan2(x, y);
1473 else if (
str ==
"\\$hypot") newNode->
realvalue = ::hypot(x, y);
1474 else if (
str ==
"\\$sinh") newNode->
realvalue = ::sinh(x);
1475 else if (
str ==
"\\$cosh") newNode->
realvalue = ::cosh(x);
1476 else if (
str ==
"\\$tanh") newNode->
realvalue = ::tanh(x);
1477 else if (
str ==
"\\$asinh") newNode->
realvalue = ::asinh(x);
1478 else if (
str ==
"\\$acosh") newNode->
realvalue = ::acosh(x);
1479 else if (
str ==
"\\$atanh") newNode->
realvalue = ::atanh(x);
1488 std::string rtype, fname;
1489 std::vector<std::string> argtypes;
1490 std::vector<AstNode*>
args;
1501 args.push_back(children.at(i-2)->clone());
1502 while (args.back()->simplify(
true,
false,
false, stage, -1,
false,
true)) { }
1508 newNode =
dpi_call(rtype, fname, argtypes, args);
1510 for (
auto arg : args)
1520 if (
str ==
"\\$readmemh" ||
str ==
"\\$readmemb")
1523 log_error(
"System function %s got %d arguments, expected 2-4 at %s:%d.\n",
1527 while (node_filename->
simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
1529 log_error(
"Failed to evaluate system function `%s' with non-constant 1st argument at %s:%d.\n",
str.c_str(),
filename.c_str(),
linenum);
1532 while (node_memory->simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
1533 if (node_memory->type !=
AST_IDENTIFIER || node_memory->id2ast ==
nullptr || node_memory->id2ast->type !=
AST_MEMORY)
1534 log_error(
"Failed to evaluate system function `%s' with non-memory 2nd argument at %s:%d.\n",
str.c_str(),
filename.c_str(),
linenum);
1536 int start_addr = -1, finish_addr = -1;
1540 while (node_addr->
simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
1542 log_error(
"Failed to evaluate system function `%s' with non-constant 3rd argument at %s:%d.\n",
str.c_str(),
filename.c_str(),
linenum);
1543 start_addr = node_addr->
asInt(
false);
1548 while (node_addr->
simplify(
true,
false,
false, stage, width_hint, sign_hint,
false)) { }
1550 log_error(
"Failed to evaluate system function `%s' with non-constant 4th argument at %s:%d.\n",
str.c_str(),
filename.c_str(),
linenum);
1551 finish_addr = node_addr->
asInt(
false);
1564 std::stringstream sstr;
1566 std::string prefix = sstr.str();
1568 bool recommend_const_eval =
false;
1570 if ((in_param || recommend_const_eval || require_const_eval) && !decl->
attributes.count(
"\\via_celltype"))
1572 bool all_args_const =
true;
1573 for (
auto child : children) {
1574 while (child->
simplify(
true,
false,
false, 1, -1,
false,
true)) { }
1576 all_args_const =
false;
1579 if (all_args_const) {
1582 delete func_workspace;
1588 if (require_const_eval)
1592 size_t arg_count = 0;
1593 std::map<std::string, std::string> replace_rules;
1602 wire = child->
clone();
1605 wire->
str = prefix +
str;
1611 while (wire->
simplify(
true,
false,
false, 1, -1,
false,
false)) { }
1620 goto replace_fcall_with_id;
1623 if (decl->
attributes.count(
"\\via_celltype"))
1625 std::string celltype = decl->
attributes.at(
"\\via_celltype")->asAttrConst().decode_string();
1626 std::string outport =
str;
1628 if (celltype.find(
' ') != std::string::npos) {
1629 int pos = celltype.find(
' ');
1636 cell->
str = prefix.substr(0,
GetSize(prefix)-1);
1640 if (attr.first.str().rfind(
"\\via_celltype_defparam_", 0) == 0)
1643 cell_arg->
str =
RTLIL::escape_id(attr.first.str().substr(strlen(
"\\via_celltype_defparam_")));
1644 cell->
children.push_back(cell_arg);
1651 wire->
str = prefix + wire->
str;
1656 while (wire->
simplify(
true,
false,
false, 1, -1,
false,
false)) { }
1659 wire_id->
str = wire->
str;
1677 cell_arg->
str = child->
str == str ? outport : child->
str;
1678 cell->
children.push_back(cell_arg);
1682 goto replace_fcall_with_id;
1689 wire->
str = prefix + wire->
str;
1694 while (wire->
simplify(
true,
false,
false, 1, -1,
false,
false)) { }
1696 replace_rules[child->
str] = wire->
str;
1702 wire_id->
str = wire->
str;
1730 replace_fcall_with_id:
1738 did_something =
true;
1745 std::vector<RTLIL::State> tmp_bits;
1747 RTLIL::Const dummy_arg;
1754 if (children.size() != 0 && children[0]->type ==
AST_RANGE && children[0]->range_valid) {
1755 std::vector<RTLIL::State> data;
1760 int tmp_range_left = children[0]->range_left, tmp_range_right = children[0]->range_right;
1762 tmp_range_left = (param_width + 2*param_offset) - children[0]->
range_right - 1;
1763 tmp_range_right = (param_width + 2*param_offset) - children[0]->
range_left - 1;
1765 for (
int i = tmp_range_right; i <= tmp_range_left; i++) {
1766 int index = i - param_offset;
1767 if (0 <= index && index < param_width)
1774 if (children.size() == 0)
1793 RTLIL::Const y = children[0]->bitsAsConst(width_hint, sign_hint);
1802 RTLIL::Const y = const_func(children[0]->
bitsAsConst(width_hint, sign_hint),
1803 children[1]->
bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint);
1813 RTLIL::Const y = const_func(RTLIL::Const(children[0]->
bits), dummy_arg,
false,
false, -1);
1829 RTLIL::Const y = const_func(RTLIL::Const(children[0]->
bits), RTLIL::Const(children[1]->
bits),
1835 newNode =
mkconst_int((children[0]->
asReal(sign_hint) != 0) && (children[1]->
asReal(sign_hint) != 0),
false, 1);
1837 newNode =
mkconst_int((children[0]->
asReal(sign_hint) != 0) || (children[1]->
asReal(sign_hint) != 0),
false, 1);
1846 RTLIL::Const y = const_func(children[0]->
bitsAsConst(width_hint, sign_hint),
1864 int cmp_width = std::max(children[0]->
bits.size(), children[1]->bits.size());
1865 bool cmp_signed = children[0]->is_signed && children[1]->is_signed;
1866 RTLIL::Const y = const_func(children[0]->
bitsAsConst(cmp_width, cmp_signed),
1867 children[1]->
bitsAsConst(cmp_width, cmp_signed), cmp_signed, cmp_signed, 1);
1891 RTLIL::Const y = const_func(children[0]->
bitsAsConst(width_hint, sign_hint),
1892 children[1]->
bitsAsConst(width_hint, sign_hint), sign_hint, sign_hint, width_hint);
1898 case AST_ADD: newNode->
realvalue = children[0]->asReal(sign_hint) + children[1]->asReal(sign_hint);
break;
1899 case AST_SUB: newNode->
realvalue = children[0]->asReal(sign_hint) - children[1]->asReal(sign_hint);
break;
1900 case AST_MUL: newNode->
realvalue = children[0]->asReal(sign_hint) * children[1]->asReal(sign_hint);
break;
1901 case AST_DIV: newNode->
realvalue = children[0]->asReal(sign_hint) / children[1]->asReal(sign_hint);
break;
1910 RTLIL::Const y = const_func(children[0]->
bitsAsConst(width_hint, sign_hint), dummy_arg, sign_hint,
false, width_hint);
1916 newNode->
realvalue = +children[0]->asReal(sign_hint);
1918 newNode->
realvalue = -children[0]->asReal(sign_hint);
1924 bool found_sure_true =
false;
1925 bool found_maybe_true =
false;
1928 for (
auto &bit : children[0]->
bits) {
1930 found_sure_true =
true;
1932 found_maybe_true =
true;
1935 found_sure_true = children[0]->asReal(sign_hint) != 0;
1938 if (found_sure_true)
1939 choice = children[1], not_choice = children[2];
1940 else if (!found_maybe_true)
1941 choice = children[2], not_choice = children[1];
1943 if (choice !=
NULL) {
1945 int other_width_hint = width_hint;
1946 bool other_sign_hint = sign_hint, other_real =
false;
1947 not_choice->
detectSignWidth(other_width_hint, other_sign_hint, &other_real);
1953 RTLIL::Const y = choice->
bitsAsConst(width_hint, sign_hint);
1954 if (choice->
is_string && y.
bits.size() % 8 == 0 && sign_hint ==
false)
1961 newNode = choice->
clone();
1964 RTLIL::Const a = children[1]->bitsAsConst(width_hint, sign_hint);
1965 RTLIL::Const b = children[2]->bitsAsConst(width_hint, sign_hint);
1967 for (
size_t i = 0; i < a.
bits.size(); i++)
1973 if (children[1]->
asReal(sign_hint) == children[2]->
asReal(sign_hint))
1974 newNode->
realvalue = children[1]->asReal(sign_hint);
1984 string_op = !children.empty();
1985 for (
auto it = children.begin(); it != children.end(); it++) {
1988 if (!(*it)->is_string)
1990 tmp_bits.insert(tmp_bits.end(), (*it)->bits.begin(), (*it)->bits.end());
1997 for (
int i = 0; i < children[0]->bitsAsConst().as_int(); i++)
1998 tmp_bits.insert(tmp_bits.end(), children.at(1)->bits.begin(), children.at(1)->bits.end());
2018 did_something =
true;
std::map< std::string, AstNode * > current_scope
RTLIL::Const bitsAsConst(int width, bool is_signed)
RTLIL::Const const_logic_or(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_xor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
static AstNode * mkconst_int(uint32_t v, bool is_signed, int width=32)
std::string stringf(const char *fmt,...)
RTLIL::Const const_pow(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
AstNode * current_top_block
AstNode * dpi_call(const std::string &rtype, const std::string &fname, const std::vector< std::string > &argtypes, const std::vector< AstNode * > &args)
void log_warning(const char *format,...)
RTLIL::Const const_ne(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
static AstNode * mkconst_bits(const std::vector< RTLIL::State > &v, bool is_signed)
RTLIL::Const const_eq(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
static AstNode * mkconst_str(const std::vector< RTLIL::State > &v)
void dumpAst(FILE *f, std::string indent)
static std::string unescape_id(std::string str)
void mem2reg_as_needed_pass1(std::map< AstNode *, std::set< std::string >> &mem2reg_places, std::map< AstNode *, uint32_t > &mem2reg_flags, std::map< AstNode *, uint32_t > &proc_flags, uint32_t &status_flags)
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
static std::string idx(std::string str)
RTLIL::Const const_sub(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_logic_not(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
void(* set_line_num)(int)
std::map< RTLIL::IdString, AstNode * > attributes
void log_error(const char *format,...)
RTLIL::Const const_or(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
bool get_bool_attribute(RTLIL::IdString id)
RTLIL::Const const_ge(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_and(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_mul(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
static std::string escape_id(std::string str)
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool did_something
RTLIL::Const const_reduce_and(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
void cloneInto(AstNode *other)
RTLIL::Const const_reduce_xor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
double asReal(bool is_signed)
RTLIL::Const const_sshl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_reduce_xnor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_xnor(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
int GetSize(RTLIL::Wire *wire)
AstNode(AstNodeType type=AST_NONE, AstNode *child1=NULL, AstNode *child2=NULL)
std::string decode_string() const
#define log_assert(_assert_expr_)
RTLIL::Const const_shr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_mod(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_shl(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
void detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real=NULL)
AstNode * current_block_child
RTLIL::Const const_le(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_eqx(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
std::vector< int > multirange_dimensions
AstNode * eval_const_function(AstNode *fcall)
RTLIL::Const const_sshr(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
void meminfo(int &mem_width, int &mem_size, int &addr_bits)
void expand_genblock(std::string index_var, std::string prefix, std::map< std::string, std::string > &name_map)
std::string current_filename
RTLIL::Const const_logic_and(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_reduce_or(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param)
RTLIL::Const const_nex(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_div(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_lt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
AstNode * current_ast_mod
void log(const char *format,...)
AstNode * readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr)
std::vector< RTLIL::State > bits
RTLIL::Const const_neg(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_add(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
std::vector< AstNode * > children
void replace_ids(const std::string &prefix, const std::map< std::string, std::string > &rules)
std::vector< RTLIL::State > bits
uint64_t asInt(bool is_signed)
RTLIL::Const const_reduce_bool(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_pos(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
RTLIL::Const const_gt(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
void mem2reg_as_needed_pass2(std::set< AstNode * > &mem2reg_set, AstNode *mod, AstNode *block)
const char * log_id(RTLIL::IdString str)
YOSYS_NAMESPACE_BEGIN int autoidx
RTLIL::Const const_not(const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
bool has_const_only_constructs(bool &recommend_const_eval)