Skip to content

Commit 5c3c56a

Browse files
committed
Fix enum with multirange
Signed-off-by: Kamil Rakoczy <[email protected]>
1 parent 56f957c commit 5c3c56a

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
@@ -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
}

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)