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