Merge pull request #210 from rakeshm75/ffs_map_update
Modified ffs map file
diff --git a/uhdm-plugin/UhdmAst.cc b/uhdm-plugin/UhdmAst.cc
index 9ec5c49..b6b541b 100644
--- a/uhdm-plugin/UhdmAst.cc
+++ b/uhdm-plugin/UhdmAst.cc
@@ -220,12 +220,17 @@
}
if (!wire_node->multirange_swapped.empty()) {
bool is_swapped = wire_node->multirange_swapped[wire_node->multirange_swapped.size() - i - 1];
+ auto right_idx = wire_node->multirange_dimensions.size() - (i * 2) - 2;
if (is_swapped) {
auto left_idx = wire_node->multirange_dimensions.size() - (i * 2) - 1;
- auto right_idx = wire_node->multirange_dimensions.size() - (i * 2) - 2;
auto elem_size = wire_node->multirange_dimensions[left_idx] - wire_node->multirange_dimensions[right_idx];
range_left = new AST::AstNode(AST::AST_SUB, AST::AstNode::mkconst_int(elem_size - 1, false), range_left->clone());
range_right = new AST::AstNode(AST::AST_SUB, AST::AstNode::mkconst_int(elem_size - 1, false), range_right->clone());
+ } else if (wire_node->multirange_dimensions[right_idx] != 0) {
+ range_left =
+ new AST::AstNode(AST::AST_SUB, range_left, AST::AstNode::mkconst_int(wire_node->multirange_dimensions[right_idx], false));
+ range_right =
+ new AST::AstNode(AST::AST_SUB, range_right, AST::AstNode::mkconst_int(wire_node->multirange_dimensions[right_idx], false));
}
}
range_left =
@@ -1279,13 +1284,16 @@
void UhdmAst::process_design()
{
current_node = make_ast_node(AST::AST_DESIGN);
- visit_one_to_many(
- {UHDM::uhdmallInterfaces, UHDM::uhdmallPackages, UHDM::uhdmallModules, UHDM::uhdmtopModules, vpiTypedef, vpiParameter, vpiParamAssign}, obj_h,
- [&](AST::AstNode *node) {
- if (node) {
- shared.top_nodes[node->str] = node;
- }
- });
+ visit_one_to_many({UHDM::uhdmallInterfaces, UHDM::uhdmallPackages, UHDM::uhdmallModules, UHDM::uhdmtopModules}, obj_h, [&](AST::AstNode *node) {
+ if (node) {
+ shared.top_nodes[node->str] = node;
+ }
+ });
+ visit_one_to_many({vpiParameter, vpiParamAssign}, obj_h, [&](AST::AstNode *node) {});
+ visit_one_to_many({vpiTypedef}, obj_h, [&](AST::AstNode *node) {
+ if (node)
+ move_type_to_new_typedef(current_node, node);
+ });
for (auto pair : shared.top_nodes) {
if (!pair.second)
continue;
@@ -1323,6 +1331,8 @@
visitEachDescendant(shared.current_top_node, [&](AST::AstNode *current_scope_node) {
if (current_scope_node->type == AST::AST_TYPEDEF || current_scope_node->type == AST::AST_PARAMETER ||
current_scope_node->type == AST::AST_LOCALPARAM) {
+ if (current_scope_node->type == AST::AST_TYPEDEF)
+ simplify(current_scope_node, nullptr);
AST_INTERNAL::current_scope[current_scope_node->str] = current_scope_node;
}
});
@@ -1330,6 +1340,8 @@
visitEachDescendant(module_node, [&](AST::AstNode *current_scope_node) {
if (current_scope_node->type == AST::AST_TYPEDEF || current_scope_node->type == AST::AST_PARAMETER ||
current_scope_node->type == AST::AST_LOCALPARAM) {
+ if (current_scope_node->type == AST::AST_TYPEDEF)
+ simplify(current_scope_node, nullptr);
AST_INTERNAL::current_scope[current_scope_node->str] = current_scope_node;
}
});
@@ -1536,6 +1548,28 @@
});
}
+void UhdmAst::process_union_typespec()
+{
+ current_node = make_ast_node(AST::AST_UNION);
+ visit_one_to_many({vpiTypespecMember}, obj_h, [&](AST::AstNode *node) {
+ if (node->children.size() > 0 && node->children[0]->type == AST::AST_ENUM) {
+ log_assert(node->children.size() == 1);
+ log_assert(!node->children[0]->children.empty());
+ log_assert(!node->children[0]->children[0]->children.empty());
+ // TODO: add missing enum_type attribute
+ auto range = make_range(0, 0);
+ // check if single enum element is larger than 1 bit
+ if (node->children[0]->children[0]->children.size() == 2) {
+ range = node->children[0]->children[0]->children[1]->clone();
+ }
+ delete node->children[0];
+ node->children.clear();
+ node->children.push_back(range);
+ }
+ current_node->children.push_back(node);
+ });
+}
+
void UhdmAst::process_array_typespec()
{
current_node = make_ast_node(AST::AST_WIRE);
@@ -1547,9 +1581,6 @@
node->cloneInto(current_node);
current_node->str = str;
delete node;
- } else if (node) {
- current_node->str = node->str;
- delete node;
}
});
visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { unpacked_ranges.push_back(node); });
@@ -1579,9 +1610,10 @@
break;
}
case vpiStructTypespec:
+ case vpiUnionTypespec:
case vpiEnumTypespec: {
visit_one_to_one({vpiTypespec}, obj_h, [&](AST::AstNode *node) {
- if (typespec_type == vpiStructTypespec) {
+ if (typespec_type == vpiStructTypespec || typespec_type == vpiUnionTypespec) {
auto str = current_node->str;
node->cloneInto(current_node);
current_node->str = str;
@@ -1684,6 +1716,21 @@
shared.report.mark_handled(typespec_h);
break;
}
+ case vpiBitTypespec: {
+ bool has_range = false;
+ visit_range(typespec_h, [&](AST::AstNode *node) {
+ has_range = true;
+ for (auto child : current_node->children) {
+ child->children.push_back(node->clone());
+ }
+ delete node;
+ });
+ if (!has_range) // range is needed for simplify
+ for (auto child : current_node->children)
+ child->children.push_back(make_ast_node(AST::AST_RANGE, {AST::AstNode::mkconst_int(0, true)}));
+ 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;
@@ -2167,7 +2214,7 @@
current_node->is_output = true;
}
}
- add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+ add_multirange_wire(current_node, packed_ranges, unpacked_ranges, false);
}
void UhdmAst::process_always()
@@ -3072,11 +3119,26 @@
void UhdmAst::process_sys_func_call()
{
current_node = make_ast_node(AST::AST_FCALL);
+
+ // skip unsupported simulation functions
+ std::string to_skip[] = {
+ "\\$value$plusargs", "\\$test$plusargs", "\\$displayb", "\\$displayh", "\\$displayo", "\\$strobeb", "\\$strobeh", "\\$strobeo",
+ "\\$writeb", "\\$writeh", "\\$writeo", "\\$dumplimit", "\\$dumpflush", "\\$fdisplay", "\\$fdisplayb", "\\$fdisplayh",
+ "\\$fdisplayo", "\\$fmonitor", "\\$fstrobe", "\\$fstrobeb", "\\$fstrobeh", "\\$fstrobeo", "\\$fwrite", "\\$fwriteb",
+ "\\$fwriteh", "\\$fwriteo", "\\$ungetc", "\\$fgetc", "\\$fgets", "\\$ftell", "\\$printtimescale"};
+
+ if (std::find(std::begin(to_skip), std::end(to_skip), current_node->str) != std::end(to_skip)) {
+ log_warning("System function %s was skipped\n", current_node->str.substr(1).c_str());
+ delete current_node;
+ current_node = nullptr;
+ return;
+ }
+
if (current_node->str == "\\$signed") {
current_node->type = AST::AST_TO_SIGNED;
} else if (current_node->str == "\\$unsigned") {
current_node->type = AST::AST_TO_UNSIGNED;
- } else if (current_node->str == "\\$display" || current_node->str == "\\$time") {
+ } else if (current_node->str == "\\$display" || current_node->str == "\\$time" || current_node->str == "\\$monitor") {
current_node->type = AST::AST_TCALL;
current_node->str = current_node->str.substr(1);
} else if (current_node->str == "\\$readmemh") {
@@ -3088,12 +3150,6 @@
current_node->children.push_back(node);
}
});
-
- // skip $value$plusargs function, as it is simulation function
- if (current_node->str == "\\$value$plusargs") {
- delete current_node;
- current_node = nullptr;
- }
}
void UhdmAst::process_func_call()
@@ -3579,6 +3635,9 @@
case vpiStructTypespec:
process_struct_typespec();
break;
+ case vpiUnionTypespec:
+ process_union_typespec();
+ break;
case vpiPackedArrayTypespec:
process_packed_array_typespec();
break;
diff --git a/uhdm-plugin/UhdmAst.h b/uhdm-plugin/UhdmAst.h
index 6d2cf5b..538ec3b 100644
--- a/uhdm-plugin/UhdmAst.h
+++ b/uhdm-plugin/UhdmAst.h
@@ -72,6 +72,7 @@
void process_port();
void process_module();
void process_struct_typespec();
+ void process_union_typespec();
void process_packed_array_typespec();
void process_array_typespec();
void process_typespec_member();