Merge pull request #417 from antmicro/rk/defaults-defines
Add systemverilog_defines, systemverilog_defaults
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index 20e68a0..6b3624a 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -1998,42 +1998,67 @@
void UhdmAst::process_enum_typespec()
{
+ // BaseTypespec specifies underlying type of the enum.
+ // The BaseTypespec has at most one explicit packed dimension (range).
+ // When base type is not specified in SystemVerilog code, it is assumed to be an int.
+ // Type of enum items (constants) is the same as the enum type.
current_node = make_ast_node(AST::AST_ENUM);
+ bool has_base_type = false;
+ visit_one_to_one({vpiBaseTypespec}, obj_h, [&](AST::AstNode *node) {
+ has_base_type = true;
+ current_node->children = std::move(node->children);
+ current_node->attributes = std::move(node->attributes);
+ current_node->is_signed = node->is_signed;
+ current_node->is_logic = node->is_logic;
+ delete node;
+ });
+ if (!has_base_type) {
+ // Base typespec is `int` by default
+ // TODO (mglb): This is almost the same code as in `process_int_typespec()`. Put common code in dedicated function.
+ std::vector<AST::AstNode *> packed_ranges;
+ packed_ranges.push_back(make_range(31, 0));
+ add_multirange_wire(current_node, std::move(packed_ranges), {});
+ current_node->is_signed = true;
+ }
+ // We have to restore node's range_* properties if there's no range.
+ const auto range_left = current_node->range_left;
+ const auto range_right = current_node->range_right;
+ const auto range_valid = current_node->range_valid;
+ // Create a range from the typespec just for the purpose of copying it to consts.
+ convert_packed_unpacked_range(current_node);
+ const auto range_it = std::find_if(current_node->children.cbegin(), current_node->children.cend(),
+ [](const AST::AstNode *n) { return n->type == AST::AST_RANGE || n->type == AST::AST_MULTIRANGE; });
+ const auto *const range = range_it != current_node->children.cend() ? *range_it : nullptr;
+ if (range) {
+ current_node->children.erase(range_it);
+ } else {
+ current_node->range_left = range_left;
+ current_node->range_right = range_right;
+ current_node->range_valid = range_valid;
+ }
+
visit_one_to_one({vpiTypedefAlias}, obj_h, [&](AST::AstNode *node) {
if (node) {
- current_node->attributes["\\enum_base_type"] = node->clone();
+ current_node->attributes["\\enum_base_type"] = node;
}
});
- visit_one_to_many({vpiEnumConst}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
- vpiHandle typespec_h = vpi_handle(vpiBaseTypespec, obj_h);
- if (typespec_h) {
- int typespec_type = vpi_get(vpiType, typespec_h);
- switch (typespec_type) {
- case vpiLogicTypespec: {
- current_node->is_logic = true;
- shared.report.mark_handled(typespec_h);
- break;
+ visit_one_to_many({vpiEnumConst}, obj_h, [&](AST::AstNode *node) {
+ // Enum const must have the same type and ranges as the enum.
+ node->is_logic = current_node->is_logic;
+ node->is_signed = current_node->is_signed;
+ if (range) {
+ node->children.push_back(range->clone());
+ node->range_valid = true;
+ } else {
+ node->range_left = range_left;
+ node->range_right = range_right;
+ node->range_valid = range_valid;
}
- case vpiByteTypespec:
- case vpiIntTypespec:
- case vpiIntegerTypespec: {
- current_node->is_signed = vpi_get(vpiSigned, typespec_h);
- shared.report.mark_handled(typespec_h);
- break;
- }
- case vpiBitTypespec: {
- shared.report.mark_handled(typespec_h);
- break;
- }
- default: {
- const uhdm_handle *const handle = (const uhdm_handle *)typespec_h;
- const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
- report_error("%s:%d: Encountered unhandled typespec in process_enum_typespec: '%s' of type '%s'\n", object->VpiFile().c_str(),
- object->VpiLineNo(), object->VpiName().c_str(), UHDM::VpiTypeName(typespec_h).c_str());
- break;
- }
- }
- vpi_release_handle(typespec_h);
+ // IMPORTANT: invalidates `range_it`!
+ current_node->children.push_back(node);
+ });
+ if (range) {
+ delete range;
}
}
@@ -2045,7 +2070,6 @@
constant_node->filename = current_node->filename;
constant_node->location = current_node->location;
current_node->children.push_back(constant_node);
- current_node->children.push_back(make_range(constant_node->range_left, constant_node->range_right, true));
}
}