@@ -496,6 +496,8 @@ static void resolve_wiretype(AST::AstNode *wire_node)
496496 unpacked_ranges.push_back (r->clone ());
497497 }
498498 }
499+ delete_attribute (wire_node, attr_id::packed_ranges);
500+ delete_attribute (wire_node, attr_id::unpacked_ranges);
499501 AST::AstNode *wiretype_ast = nullptr ;
500502 log_assert (AST_INTERNAL::current_scope.count (wiretype_node->str ));
501503 wiretype_ast = AST_INTERNAL::current_scope[wiretype_node->str ];
@@ -512,55 +514,48 @@ static void resolve_wiretype(AST::AstNode *wire_node)
512514 wire_node->children [0 ]->range_left = struct_width;
513515 wire_node->children [0 ]->children [0 ]->integer = struct_width;
514516 }
515- if (wiretype_ast && wire_node->attributes .count (ID::wiretype)) {
517+ if (wiretype_ast) {
518+ log_assert (wire_node->attributes .count (ID::wiretype));
516519 log_assert (wiretype_ast->type == AST::AST_TYPEDEF);
517520 wire_node->attributes [ID::wiretype]->id2ast = wiretype_ast->children [0 ];
518521 }
519522 if ((wire_node->children [0 ]->type == AST::AST_RANGE || (wire_node->children .size () > 1 && wire_node->children [1 ]->type == AST::AST_RANGE)) &&
520523 wire_node->multirange_dimensions .empty ()) {
524+ // We need to save order in which ranges appear in wiretype and add them before wire range
525+ // We need to copy this ranges, so create new vector for them
526+ std::vector<AST::AstNode *> packed_ranges_wiretype;
527+ std::vector<AST::AstNode *> unpacked_ranges_wiretype;
521528 if (wiretype_ast && !wiretype_ast->children .empty () && wiretype_ast->children [0 ]->attributes .count (UhdmAst::packed_ranges ()) &&
522529 wiretype_ast->children [0 ]->attributes .count (UhdmAst::unpacked_ranges ())) {
523530 for (auto r : wiretype_ast->children [0 ]->attributes [UhdmAst::packed_ranges ()]->children ) {
524- packed_ranges .push_back (r->clone ());
531+ packed_ranges_wiretype .push_back (r->clone ());
525532 }
526533 for (auto r : wiretype_ast->children [0 ]->attributes [UhdmAst::unpacked_ranges ()]->children ) {
527- unpacked_ranges .push_back (r->clone ());
534+ unpacked_ranges_wiretype .push_back (r->clone ());
528535 }
529536 } else {
530537 if (wire_node->children [0 ]->type == AST::AST_RANGE)
531- packed_ranges .push_back (wire_node->children [0 ]->clone ());
538+ packed_ranges_wiretype .push_back (wire_node->children [0 ]->clone ());
532539 else if (wire_node->children [1 ]->type == AST::AST_RANGE)
533- packed_ranges .push_back (wire_node->children [1 ]->clone ());
540+ packed_ranges_wiretype .push_back (wire_node->children [1 ]->clone ());
534541 else
535542 log_error (" Unhandled case in resolve_wiretype!\n " );
536543 }
544+ // add wiretype range before current wire ranges
545+ std::reverse (packed_ranges_wiretype.begin (), packed_ranges_wiretype.end ());
546+ std::reverse (unpacked_ranges_wiretype.begin (), unpacked_ranges_wiretype.end ());
547+ std::reverse (packed_ranges.begin (), packed_ranges.end ());
548+ std::reverse (unpacked_ranges.begin (), unpacked_ranges.end ());
549+ packed_ranges.insert (packed_ranges.begin (), packed_ranges_wiretype.begin (), packed_ranges_wiretype.end ());
550+ unpacked_ranges.insert (unpacked_ranges.begin (), unpacked_ranges_wiretype.begin (), unpacked_ranges_wiretype.end ());
537551 AST::AstNode *value = nullptr ;
538552 if (wire_node->children [0 ]->type != AST::AST_RANGE) {
539553 value = wire_node->children [0 ]->clone ();
540554 }
541555 delete_children (wire_node);
542556 if (value)
543557 wire_node->children .push_back (value);
544- wire_node->attributes [UhdmAst::packed_ranges ()] = AST::AstNode::mkconst_int (1 , false , 1 );
545- if (!packed_ranges.empty ()) {
546- std::reverse (packed_ranges.begin (), packed_ranges.end ());
547- wire_node->attributes [UhdmAst::packed_ranges ()]->children .insert (wire_node->attributes [UhdmAst::packed_ranges ()]->children .end (),
548- packed_ranges.begin (), packed_ranges.end ());
549- packed_ranges.clear ();
550- }
551-
552- wire_node->attributes [UhdmAst::unpacked_ranges ()] = AST::AstNode::mkconst_int (1 , false , 1 );
553- if (!unpacked_ranges.empty ()) {
554- wire_node->attributes [UhdmAst::unpacked_ranges ()]->children .insert (wire_node->attributes [UhdmAst::unpacked_ranges ()]->children .end (),
555- unpacked_ranges.begin (), unpacked_ranges.end ());
556- unpacked_ranges.clear ();
557- }
558- }
559- for (auto *range : packed_ranges) {
560- delete range;
561- }
562- for (auto *range : unpacked_ranges) {
563- delete range;
558+ add_multirange_wire (wire_node, packed_ranges, unpacked_ranges, false /* reverse */ );
564559 }
565560}
566561
@@ -748,11 +743,6 @@ static void convert_packed_unpacked_range(AST::AstNode *wire_node)
748743 }
749744 }
750745
751- if (wire_node->type == AST::AST_STRUCT_ITEM || wire_node->type == AST::AST_STRUCT) {
752- delete_attribute (wire_node, UhdmAst::packed_ranges ());
753- delete_attribute (wire_node, UhdmAst::unpacked_ranges ());
754- }
755-
756746 // Insert new range
757747 wire_node->children .insert (wire_node->children .end (), ranges.begin (), ranges.end ());
758748}
@@ -1354,12 +1344,13 @@ static void simplify_sv(AST::AstNode *current_node, AST::AstNode *parent_node)
13541344 }
13551345 break ;
13561346 case AST::AST_STRUCT_ITEM:
1357- AST_INTERNAL::current_scope[current_node->str ] = current_node;
1358- if (current_node->attributes .count (UhdmAst::packed_ranges ()) || current_node->attributes .count (UhdmAst::unpacked_ranges ())) {
1347+ if (!current_node->attributes .count (UhdmAst::is_simplified_wire ())) {
1348+ current_node->attributes [UhdmAst::is_simplified_wire ()] = AST::AstNode::mkconst_int (1 , true );
1349+ AST_INTERNAL::current_scope[current_node->str ] = current_node;
13591350 convert_packed_unpacked_range (current_node);
1351+ while (simplify (current_node, true , false , false , 1 , -1 , false , false )) {
1352+ };
13601353 }
1361- while (simplify (current_node, true , false , false , 1 , -1 , false , false )) {
1362- };
13631354 break ;
13641355 case AST::AST_TCALL:
13651356 if (current_node->str == " $display" || current_node->str == " $write" )
@@ -1844,17 +1835,15 @@ void UhdmAst::process_packed_array_typespec()
18441835 current_node->str = str;
18451836 delete node;
18461837 } else if (node) {
1847- current_node->str = node->str ;
1848- if (node->type == AST::AST_ENUM && !node->children .empty ()) {
1849- for (auto *c : node->children [0 ]->children ) {
1850- if (c->type == AST::AST_RANGE && c->str .empty ())
1851- packed_ranges.push_back (c);
1852- else
1853- delete c;
1854- }
1855- node->children [0 ]->children .clear ();
1838+ if (!node->str .empty ()) {
1839+ AST::AstNode *const wiretype_node = make_named_node (AST::AST_WIRETYPE);
1840+ wiretype_node->str = node->str ;
1841+ current_node->children .push_back (wiretype_node);
1842+ current_node->is_custom_type = true ;
1843+ auto it = shared.param_types .find (current_node->str );
1844+ if (it == shared.param_types .end ())
1845+ shared.param_types .insert (std::make_pair (current_node->str , node->clone ()));
18561846 }
1857- delete node;
18581847 }
18591848 });
18601849 add_multirange_wire (current_node, std::move (packed_ranges), std::move (unpacked_ranges));
@@ -2026,15 +2015,17 @@ void UhdmAst::move_type_to_new_typedef(AST::AstNode *current_node, AST::AstNode
20262015 delete type_node;
20272016 } else {
20282017 type_node->str = " $enum" + std::to_string (shared.next_enum_id ());
2018+ std::vector<AST::AstNode *> packed_ranges;
20292019 auto wire_node = new AST::AstNode (AST::AST_WIRE);
20302020 wire_node->is_reg = true ;
20312021 wire_node->attributes [" \\ enum_type" ] = AST::AstNode::mkconst_str (type_node->str );
20322022 if (!type_node->children .empty () && type_node->children [0 ]->children .size () > 1 ) {
2033- wire_node-> children .push_back (type_node->children [0 ]->children [1 ]->clone ());
2023+ packed_ranges .push_back (type_node->children [0 ]->children [1 ]->clone ());
20342024 } else {
20352025 // Add default range
2036- wire_node-> children .push_back (make_range (31 , 0 ));
2026+ packed_ranges .push_back (make_range (31 , 0 ));
20372027 }
2028+ add_multirange_wire (wire_node, std::move (packed_ranges), {});
20382029 typedef_node->children .push_back (wire_node);
20392030 current_node->children .push_back (type_node);
20402031 current_node->children .push_back (typedef_node);
@@ -4468,6 +4459,8 @@ void UhdmAst::process_logic_typespec()
44684459 }
44694460 }
44704461 visit_one_to_many ({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back (node); });
4462+ if (packed_ranges.empty ())
4463+ packed_ranges.push_back (make_range (0 , 0 ));
44714464 add_multirange_wire (current_node, packed_ranges, unpacked_ranges);
44724465 current_node->is_signed = vpi_get (vpiSigned, obj_h);
44734466}
0 commit comments