@@ -502,6 +502,8 @@ static void resolve_wiretype(AST::AstNode *wire_node)
502502 unpacked_ranges.push_back (r->clone ());
503503 }
504504 }
505+ delete_attribute (wire_node, attr_id::packed_ranges);
506+ delete_attribute (wire_node, attr_id::unpacked_ranges);
505507 AST::AstNode *wiretype_ast = nullptr ;
506508 log_assert (AST_INTERNAL::current_scope.count (wiretype_node->str ));
507509 wiretype_ast = AST_INTERNAL::current_scope[wiretype_node->str ];
@@ -518,55 +520,48 @@ static void resolve_wiretype(AST::AstNode *wire_node)
518520 wire_node->children [0 ]->range_left = struct_width;
519521 wire_node->children [0 ]->children [0 ]->integer = struct_width;
520522 }
521- if (wiretype_ast && wire_node->attributes .count (ID::wiretype)) {
523+ if (wiretype_ast) {
524+ log_assert (wire_node->attributes .count (ID::wiretype));
522525 log_assert (wiretype_ast->type == AST::AST_TYPEDEF);
523526 wire_node->attributes [ID::wiretype]->id2ast = wiretype_ast->children [0 ];
524527 }
525528 if ((wire_node->children [0 ]->type == AST::AST_RANGE || (wire_node->children .size () > 1 && wire_node->children [1 ]->type == AST::AST_RANGE)) &&
526529 wire_node->multirange_dimensions .empty ()) {
530+ // We need to save order in which ranges appear in wiretype and add them before wire range
531+ // We need to copy this ranges, so create new vector for them
532+ std::vector<AST::AstNode *> packed_ranges_wiretype;
533+ std::vector<AST::AstNode *> unpacked_ranges_wiretype;
527534 if (wiretype_ast && !wiretype_ast->children .empty () && wiretype_ast->children [0 ]->attributes .count (UhdmAst::packed_ranges ()) &&
528535 wiretype_ast->children [0 ]->attributes .count (UhdmAst::unpacked_ranges ())) {
529536 for (auto r : wiretype_ast->children [0 ]->attributes [UhdmAst::packed_ranges ()]->children ) {
530- packed_ranges .push_back (r->clone ());
537+ packed_ranges_wiretype .push_back (r->clone ());
531538 }
532539 for (auto r : wiretype_ast->children [0 ]->attributes [UhdmAst::unpacked_ranges ()]->children ) {
533- unpacked_ranges .push_back (r->clone ());
540+ unpacked_ranges_wiretype .push_back (r->clone ());
534541 }
535542 } else {
536543 if (wire_node->children [0 ]->type == AST::AST_RANGE)
537- packed_ranges .push_back (wire_node->children [0 ]->clone ());
544+ packed_ranges_wiretype .push_back (wire_node->children [0 ]->clone ());
538545 else if (wire_node->children [1 ]->type == AST::AST_RANGE)
539- packed_ranges .push_back (wire_node->children [1 ]->clone ());
546+ packed_ranges_wiretype .push_back (wire_node->children [1 ]->clone ());
540547 else
541548 log_error (" Unhandled case in resolve_wiretype!\n " );
542549 }
550+ // add wiretype range before current wire ranges
551+ std::reverse (packed_ranges_wiretype.begin (), packed_ranges_wiretype.end ());
552+ std::reverse (unpacked_ranges_wiretype.begin (), unpacked_ranges_wiretype.end ());
553+ std::reverse (packed_ranges.begin (), packed_ranges.end ());
554+ std::reverse (unpacked_ranges.begin (), unpacked_ranges.end ());
555+ packed_ranges.insert (packed_ranges.begin (), packed_ranges_wiretype.begin (), packed_ranges_wiretype.end ());
556+ unpacked_ranges.insert (unpacked_ranges.begin (), unpacked_ranges_wiretype.begin (), unpacked_ranges_wiretype.end ());
543557 AST::AstNode *value = nullptr ;
544558 if (wire_node->children [0 ]->type != AST::AST_RANGE) {
545559 value = wire_node->children [0 ]->clone ();
546560 }
547561 delete_children (wire_node);
548562 if (value)
549563 wire_node->children .push_back (value);
550- wire_node->attributes [UhdmAst::packed_ranges ()] = AST::AstNode::mkconst_int (1 , false , 1 );
551- if (!packed_ranges.empty ()) {
552- std::reverse (packed_ranges.begin (), packed_ranges.end ());
553- wire_node->attributes [UhdmAst::packed_ranges ()]->children .insert (wire_node->attributes [UhdmAst::packed_ranges ()]->children .end (),
554- packed_ranges.begin (), packed_ranges.end ());
555- packed_ranges.clear ();
556- }
557-
558- wire_node->attributes [UhdmAst::unpacked_ranges ()] = AST::AstNode::mkconst_int (1 , false , 1 );
559- if (!unpacked_ranges.empty ()) {
560- wire_node->attributes [UhdmAst::unpacked_ranges ()]->children .insert (wire_node->attributes [UhdmAst::unpacked_ranges ()]->children .end (),
561- unpacked_ranges.begin (), unpacked_ranges.end ());
562- unpacked_ranges.clear ();
563- }
564- }
565- for (auto *range : packed_ranges) {
566- delete range;
567- }
568- for (auto *range : unpacked_ranges) {
569- delete range;
564+ add_multirange_wire (wire_node, packed_ranges, unpacked_ranges, false /* reverse */ );
570565 }
571566}
572567
@@ -754,11 +749,6 @@ static void convert_packed_unpacked_range(AST::AstNode *wire_node)
754749 }
755750 }
756751
757- if (wire_node->type == AST::AST_STRUCT_ITEM || wire_node->type == AST::AST_STRUCT) {
758- delete_attribute (wire_node, UhdmAst::packed_ranges ());
759- delete_attribute (wire_node, UhdmAst::unpacked_ranges ());
760- }
761-
762752 // Insert new range
763753 wire_node->children .insert (wire_node->children .end (), ranges.begin (), ranges.end ());
764754}
@@ -1360,12 +1350,13 @@ static void simplify_sv(AST::AstNode *current_node, AST::AstNode *parent_node)
13601350 }
13611351 break ;
13621352 case AST::AST_STRUCT_ITEM:
1363- AST_INTERNAL::current_scope[current_node->str ] = current_node;
1364- if (current_node->attributes .count (UhdmAst::packed_ranges ()) || current_node->attributes .count (UhdmAst::unpacked_ranges ())) {
1353+ if (!current_node->attributes .count (UhdmAst::is_simplified_wire ())) {
1354+ current_node->attributes [UhdmAst::is_simplified_wire ()] = AST::AstNode::mkconst_int (1 , true );
1355+ AST_INTERNAL::current_scope[current_node->str ] = current_node;
13651356 convert_packed_unpacked_range (current_node);
1357+ while (simplify (current_node, true , false , false , 1 , -1 , false , false )) {
1358+ };
13661359 }
1367- while (simplify (current_node, true , false , false , 1 , -1 , false , false )) {
1368- };
13691360 break ;
13701361 case AST::AST_TCALL:
13711362 if (current_node->str == " $display" || current_node->str == " $write" )
@@ -1850,17 +1841,15 @@ void UhdmAst::process_packed_array_typespec()
18501841 current_node->str = str;
18511842 delete node;
18521843 } else if (node) {
1853- current_node->str = node->str ;
1854- if (node->type == AST::AST_ENUM && !node->children .empty ()) {
1855- for (auto *c : node->children [0 ]->children ) {
1856- if (c->type == AST::AST_RANGE && c->str .empty ())
1857- packed_ranges.push_back (c);
1858- else
1859- delete c;
1860- }
1861- node->children [0 ]->children .clear ();
1844+ if (!node->str .empty ()) {
1845+ AST::AstNode *const wiretype_node = make_named_node (AST::AST_WIRETYPE);
1846+ wiretype_node->str = node->str ;
1847+ current_node->children .push_back (wiretype_node);
1848+ current_node->is_custom_type = true ;
1849+ auto it = shared.param_types .find (current_node->str );
1850+ if (it == shared.param_types .end ())
1851+ shared.param_types .insert (std::make_pair (current_node->str , node->clone ()));
18621852 }
1863- delete node;
18641853 }
18651854 });
18661855 add_multirange_wire (current_node, std::move (packed_ranges), std::move (unpacked_ranges));
@@ -2032,15 +2021,17 @@ void UhdmAst::move_type_to_new_typedef(AST::AstNode *current_node, AST::AstNode
20322021 delete type_node;
20332022 } else {
20342023 type_node->str = " $enum" + std::to_string (shared.next_enum_id ());
2024+ std::vector<AST::AstNode *> packed_ranges;
20352025 auto wire_node = new AST::AstNode (AST::AST_WIRE);
20362026 wire_node->is_reg = true ;
20372027 wire_node->attributes [" \\ enum_type" ] = AST::AstNode::mkconst_str (type_node->str );
20382028 if (!type_node->children .empty () && type_node->children [0 ]->children .size () > 1 ) {
2039- wire_node-> children .push_back (type_node->children [0 ]->children [1 ]->clone ());
2029+ packed_ranges .push_back (type_node->children [0 ]->children [1 ]->clone ());
20402030 } else {
20412031 // Add default range
2042- wire_node-> children .push_back (make_range (31 , 0 ));
2032+ packed_ranges .push_back (make_range (31 , 0 ));
20432033 }
2034+ add_multirange_wire (wire_node, std::move (packed_ranges), {});
20442035 typedef_node->children .push_back (wire_node);
20452036 current_node->children .push_back (type_node);
20462037 current_node->children .push_back (typedef_node);
@@ -4481,6 +4472,8 @@ void UhdmAst::process_logic_typespec()
44814472 }
44824473 }
44834474 visit_one_to_many ({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back (node); });
4475+ if (packed_ranges.empty ())
4476+ packed_ranges.push_back (make_range (0 , 0 ));
44844477 add_multirange_wire (current_node, packed_ranges, unpacked_ranges);
44854478 current_node->is_signed = vpi_get (vpiSigned, obj_h);
44864479}
0 commit comments