Skip to content

Commit 188555f

Browse files
authored
Merge pull request chipsalliance#507 from antmicro/kr/fix_enum_multirange
systemverilog-plugin: fix packed arrays of enums
2 parents 8edc027 + 5c3c56a commit 188555f

File tree

2 files changed

+40
-47
lines changed

2 files changed

+40
-47
lines changed

systemverilog-plugin/UhdmAst.cc

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

systemverilog-plugin/third_party/yosys/simplify.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
14851485
}
14861486

14871487
// resolve types of wires
1488-
if (ast_node->type == Yosys::AST::AST_WIRE || ast_node->type == Yosys::AST::AST_MEMORY) {
1488+
if (ast_node->type == Yosys::AST::AST_WIRE || ast_node->type == Yosys::AST::AST_MEMORY || ast_node->type == Yosys::AST::AST_STRUCT_ITEM) {
14891489
if (ast_node->is_custom_type) {
14901490
log_assert(ast_node->children.size() >= 1);
14911491
log_assert(ast_node->children[0]->type == Yosys::AST::AST_WIRETYPE);

0 commit comments

Comments
 (0)