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