Merge pull request #392 from antmicro/assign-op-type

systemverilog: Support op type on assignment
diff --git a/ql-qlf-plugin/ql-dsp-simd.cc b/ql-qlf-plugin/ql-dsp-simd.cc
index 7893eb4..2528879 100644
--- a/ql-qlf-plugin/ql-dsp-simd.cc
+++ b/ql-qlf-plugin/ql-dsp-simd.cc
@@ -162,7 +162,7 @@
                     const RTLIL::Cell *dsp_a = group[i];
                     const RTLIL::Cell *dsp_b = group[i + 1];
 
-                    std::string name = stringf("simd_%s_%s", RTLIL::unescape_id(dsp_a->name).c_str(), RTLIL::unescape_id(dsp_b->name).c_str());
+                    std::string name = stringf("simd%ld", i / 2);
                     std::string SimdDspType;
 
                     if (use_cfg_params)
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index 10b76df..6790fe9 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -470,10 +470,13 @@
         // we get left range for first children, and right range for last children
         left = AST::AstNode::mkconst_int(current_struct_elem->children.front()->range_left, true);
         right = AST::AstNode::mkconst_int(current_struct_elem->children.back()->range_right, true);
+    } else if (current_struct_elem->type == AST::AST_UNION) {
+        left = AST::AstNode::mkconst_int(current_struct_elem->range_left, true);
+        right = AST::AstNode::mkconst_int(current_struct_elem->range_right, true);
     } else {
-        // Structs currently can only have AST_STRUCT or AST_STRUCT_ITEM
-        // so, it should never happen
-        log_error("Found %s elem in struct that is currently unsupported!\n", type2str(current_struct_elem->type).c_str());
+        // Structs currently can only have AST_STRUCT, AST_STRUCT_ITEM, or AST_UNION.
+        log_file_error(current_struct_elem->filename, current_struct_elem->location.first_line,
+                       "Accessing struct member of type %s is unsupported.\n", type2str(current_struct_elem->type).c_str());
     }
 
     auto elem_size =
@@ -549,7 +552,8 @@
                 log_error("Unhandled range select (AST_STRUCT) in AST_DOT!\n");
             }
         } else {
-            log_error("Found %s elem in struct that is currently unsupported!\n", type2str(current_struct_elem->type).c_str());
+            log_file_error(current_struct_elem->filename, current_struct_elem->location.first_line,
+                           "Accessing member of a slice of type %s is unsupported.\n", type2str(current_struct_elem->type).c_str());
         }
     }
     // Return range from the begining of *current* struct
@@ -561,11 +565,13 @@
 static AST::AstNode *convert_dot(AST::AstNode *wire_node, AST::AstNode *node, AST::AstNode *dot)
 {
     AST::AstNode *struct_node = nullptr;
-    if (wire_node->type == AST::AST_STRUCT) {
+    if (wire_node->type == AST::AST_STRUCT || wire_node->type == AST::AST_UNION) {
         struct_node = wire_node;
     } else if (wire_node->attributes.count(ID::wiretype)) {
         log_assert(wire_node->attributes[ID::wiretype]->id2ast);
         struct_node = wire_node->attributes[ID::wiretype]->id2ast;
+    } else {
+        log_file_error(wire_node->filename, wire_node->location.first_line, "Unsupported node type: %s\n", type2str(wire_node->type).c_str());
     }
     log_assert(struct_node);
     auto expanded = expand_dot(struct_node, dot);
@@ -1325,6 +1331,7 @@
                 if (child->type == AST::AST_MEMORY)
                     child->type = AST::AST_WIRE;
             }
+            child->is_signed = (*it)->is_signed;
             if (!(*it)->children.empty() && child->children.empty()) {
                 // This is a bit ugly, but if the child we're replacing has children and
                 // our node doesn't, we copy its children to not lose any information
@@ -3589,6 +3596,7 @@
     }
     visit_one_to_many({vpiRange}, obj_h, [&](AST::AstNode *node) { packed_ranges.push_back(node); });
     add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
+    current_node->is_signed = vpi_get(vpiSigned, obj_h);
 }
 
 void UhdmAst::process_int_typespec()
@@ -3598,7 +3606,7 @@
     current_node = make_ast_node(AST::AST_WIRE);
     packed_ranges.push_back(make_range(31, 0));
     add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
-    current_node->is_signed = true;
+    current_node->is_signed = vpi_get(vpiSigned, obj_h);
 }
 
 void UhdmAst::process_shortint_typespec()
@@ -3608,7 +3616,7 @@
     current_node = make_ast_node(AST::AST_WIRE);
     packed_ranges.push_back(make_range(15, 0));
     add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
-    current_node->is_signed = true;
+    current_node->is_signed = vpi_get(vpiSigned, obj_h);
 }
 
 void UhdmAst::process_longint_typespec()
@@ -3618,7 +3626,7 @@
     current_node = make_ast_node(AST::AST_WIRE);
     packed_ranges.push_back(make_range(63, 0));
     add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
-    current_node->is_signed = true;
+    current_node->is_signed = vpi_get(vpiSigned, obj_h);
 }
 
 void UhdmAst::process_byte_typespec()
@@ -3628,7 +3636,7 @@
     current_node = make_ast_node(AST::AST_WIRE);
     packed_ranges.push_back(make_range(7, 0));
     add_multirange_wire(current_node, packed_ranges, unpacked_ranges);
-    current_node->is_signed = true;
+    current_node->is_signed = vpi_get(vpiSigned, obj_h);
 }
 
 void UhdmAst::process_time_typespec()
@@ -3691,6 +3699,7 @@
             current_node->children.push_back(node);
         }
     });
+    current_node->is_signed = vpi_get(vpiSigned, obj_h);
 }
 
 void UhdmAst::process_repeat()
@@ -3844,6 +3853,7 @@
                     current_node->children = std::move(node->children);
                 }
             }
+            current_node->is_signed = node->is_signed;
             delete node;
         }
     });