systemverilog-plugin: add support for case type in process_value

Signed-off-by: Kamil Rakoczy <krakoczy@antmicro.com>
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index 3eb0e30..5c845af 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -1213,9 +1213,33 @@
                          object->VpiLineNo(), val.format);
         }
         }
+        // if this constant is under case/casex/casez
+        // get current case type
+        char caseType = ' ';
+        if (vpiHandle caseItem_h = vpi_handle(vpiParent, obj_h)) {
+            if (vpiHandle case_h = vpi_handle(vpiParent, caseItem_h)) {
+                switch (vpi_get(vpiCaseType, case_h)) {
+                case vpiCaseExact:
+                    caseType = ' ';
+                    break;
+                case vpiCaseX:
+                    caseType = 'x';
+                    break;
+                case vpiCaseZ:
+                    caseType = 'z';
+                    break;
+                default: {
+                    caseType = ' ';
+                    break;
+                }
+                }
+                vpi_release_handle(case_h);
+            }
+            vpi_release_handle(caseItem_h);
+        }
         // handle vpiBinStrVal, vpiDecStrVal and vpiHexStrVal
         if (std::strchr(val.value.str, '\'')) {
-            return ::systemverilog_plugin::const2ast(val.value.str, 0, false);
+            return ::systemverilog_plugin::const2ast(val.value.str, caseType, false);
         } else {
             auto size = vpi_get(vpiSize, obj_h);
             if (size == 0) {
@@ -1223,7 +1247,7 @@
                 c->is_unsized = true;
                 return c;
             } else {
-                return ::systemverilog_plugin::const2ast(std::to_string(size) + strValType + val.value.str, 0, false);
+                return ::systemverilog_plugin::const2ast(std::to_string(size) + strValType + val.value.str, caseType, false);
             }
         }
     }
@@ -3430,42 +3454,33 @@
 void UhdmAst::process_case()
 {
     current_node = make_ast_node(AST::AST_CASE);
-    auto cond_type = AST::AST_COND;
-    switch (vpi_get(vpiCaseType, obj_h)) {
-    case vpiCaseExact:
-        cond_type = AST::AST_COND;
-        break;
-    case vpiCaseX:
-        cond_type = AST::AST_CONDX;
-        break;
-    case vpiCaseZ:
-        cond_type = AST::AST_CONDZ;
-        break;
-    default: {
-        const uhdm_handle *const handle = (const uhdm_handle *)obj_h;
-        const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
-        report_error("%.*s:%d: Unknown case type", (int)object->VpiFile().length(), object->VpiFile().data(), object->VpiLineNo());
-    }
-    }
     visit_one_to_one({vpiCondition}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
-    visit_one_to_many({vpiCaseItem}, obj_h, [&](AST::AstNode *node) {
-        node->type = cond_type;
-        // TODO(krak): We are changing here Sx to Sz to match
-        // yosys read_verilog -sv output
-        if (cond_type == AST::AST_CONDX) {
-            for (unsigned i = 0; i < node->bits.size(); i++) {
-                if (node->bits[i] == RTLIL::State::Sx) {
-                    node->bits[i] = RTLIL::State::Sz;
-                }
-            }
-        }
-        current_node->children.push_back(node);
-    });
+    visit_one_to_many({vpiCaseItem}, obj_h, [&](AST::AstNode *node) { current_node->children.push_back(node); });
 }
 
 void UhdmAst::process_case_item()
 {
-    current_node = make_ast_node(AST::AST_COND);
+    auto cond_type = AST::AST_COND;
+    if (vpiHandle parent_h = vpi_handle(vpiParent, obj_h)) {
+        switch (vpi_get(vpiCaseType, parent_h)) {
+        case vpiCaseExact:
+            cond_type = AST::AST_COND;
+            break;
+        case vpiCaseX:
+            cond_type = AST::AST_CONDX;
+            break;
+        case vpiCaseZ:
+            cond_type = AST::AST_CONDZ;
+            break;
+        default: {
+            const uhdm_handle *const handle = (const uhdm_handle *)obj_h;
+            const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
+            report_error("%.*s:%d: Unknown case type", (int)object->VpiFile().length(), object->VpiFile().data(), object->VpiLineNo());
+        }
+        }
+        vpi_release_handle(parent_h);
+    }
+    current_node = make_ast_node(cond_type);
     vpiHandle itr = vpi_iterate(vpiExpr, obj_h);
     while (vpiHandle expr_h = vpi_scan(itr)) {
         // case ... inside statement, the operation is stored in UHDM inside case items