diff --git a/include/verilated.h b/include/verilated.h index 4e4503a8db..77deeefb1a 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -133,7 +133,8 @@ enum VerilatedVarType : uint8_t { VLVT_UINT32, // AKA IData VLVT_UINT64, // AKA QData VLVT_WDATA, // AKA WData - VLVT_STRING // C++ string + VLVT_STRING, // C++ string + VLVT_REAL // AKA double }; enum VerilatedVarFlags { diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 2e021f2c5d..7e01fe5d27 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -303,7 +303,13 @@ class VerilatedVpioVar VL_NOT_FINAL : public VerilatedVpioVarBase { uint32_t entSize() const { return m_entSize; } uint32_t index() const { return m_index; } uint32_t type() const override { - return (varp()->dims() > 1) ? vpiMemory : vpiReg; // but might be wire, logic + uint32_t type = vpiReg; + switch (varp()->vltype()) { + case VLVT_REAL: type = vpiRealVar; break; + case VLVT_STRING: type = vpiStringVar; break; + default: break; + } + return (varp()->dims() > 1) ? vpiMemory : type; // but might be wire, logic } void* prevDatap() const { return m_prevDatap; } void* varDatap() const { return m_varDatap; } @@ -985,9 +991,117 @@ const char* VerilatedVpiError::strFromVpiObjType(PLI_INT32 vpiVal) VL_PURE { "vpiGenVar", "vpiAutomatics" }; + static const char* const sv_names1[] = { + "vpiPackage", + "vpiInterface", + "vpiProgram", + "vpiInterfaceArray", + "vpiProgramArray", + "vpiTypespec", + "vpiModport", + "vpiInterfaceTfDecl", + "vpiRefObj", + "vpiTypeParameter", + "vpiLongIntVar", + "vpiShortIntVar", + "vpiIntVar", + "vpiShortRealVar", + "vpiByteVar", + "vpiClassVar", + "vpiStringVar", + "vpiEnumVar", + "vpiStructVar", + "vpiUnionVar", + "vpiBitVar", + "vpiClassObj", + "vpiChandleVar", + "vpiPackedArrayVar", + "*undefined*", // 624 is not defined for object types + "vpiLongIntTypespec", + "vpiShortRealTypespec", + "vpiByteTypespec", + "vpiShortIntTypespec", + "vpiIntTypespec", + "vpiClassTypespec", + "vpiStringTypespec", + "vpiChandleTypespec", + "vpiEnumTypespec", + "vpiEnumConst", + "vpiIntegerTypespec", + "vpiTimeTypespec", + "vpiRealTypespec", + "vpiStructTypespec", + "vpiUnionTypespec", + "vpiBitTypespec", + "vpiLogicTypespec", + "vpiArrayTypespec", + "vpiVoidTypespec", + "vpiTypespecMember", + "vpiDistItem", + "vpiAliasStmt", + "vpiThread", + "vpiMethodFuncCall", + "vpiMethodTaskCall", + "vpiClockingBlock", + "vpiClockingIODecl", + "vpiClassDefn", + "vpiConstraint", + "vpiConstraintOrdering", + "vpiPropertyDecl", + "vpiPropertySpec", + "vpiPropertyExpr", + "vpiMulticlockSequenceExpr", + "vpiClockedSeq", + "vpiPropertyInst", + "vpiSequenceDecl", + "vpiCaseProperty", + "*undefined*", // 663 is not defined for object types + "vpiSequenceInst", + "vpiImmediateAssert", + "vpiReturn", + "vpiAnyPattern", + "vpiTaggedPattern", + "vpiStructPattern", + "vpiDoWhile", + "vpiOrderedWait", + "vpiWaitFork", + "vpiDisableFork", + "vpiExpectStmt", + "vpiForeachStmt", + "vpiFinal", + "vpiExtends", + "vpiDistribution", + "vpiSeqFormalDecl", + "vpiEnumNet", + "vpiIntegerNet", + "vpiTimeNet", + "vpiStructNet", + "vpiBreak", + "vpiContinue", + "vpiAssert", + "vpiAssume", + "vpiCover", + "vpiDisableCondition", + "vpiClockingEvent", + "vpiReturnStmt", + "vpiPackedArrayTypespec", + "vpiPackedArrayNet", + "vpiImmediateAssume", + "vpiImmediateCover", + "vpiSequenceTypespec", + "vpiPropertyTypespec", + "vpiEventTypespec", + "vpiPropFormalDecl", + }; // clang-format on - if (VL_UNCOVERABLE(vpiVal < 0)) return names[0]; - return names[(vpiVal <= vpiAutomatics) ? vpiVal : 0]; + if (VL_UNCOVERABLE(vpiVal < 0)) + return names[0]; + else if (vpiVal <= vpiAutomatics) + return names[vpiVal]; + else if (vpiVal >= vpiPackage && vpiVal <= vpiPropFormalDecl) + return sv_names1[(vpiVal - vpiPackage)]; + else + return names[0]; } const char* VerilatedVpiError::strFromVpiMethod(PLI_INT32 vpiVal) VL_PURE { // clang-format off @@ -1313,6 +1427,104 @@ void VerilatedVpiError::selfTest() VL_MT_UNSAFE_ONE { SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiGenScope); SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiGenVar); SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiAutomatics); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiPackage); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiInterface); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiProgram); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiInterfaceArray); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiProgramArray); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiModport); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiInterfaceTfDecl); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiRefObj); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiTypeParameter); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiLongIntVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiShortIntVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiIntVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiShortRealVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiByteVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiClassVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiStringVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiEnumVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiStructVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiUnionVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiBitVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiClassObj); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiChandleVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiPackedArrayVar); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiLongIntTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiShortRealTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiByteTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiShortIntTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiIntTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiClassTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiStringTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiChandleTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiEnumTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiEnumConst); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiIntegerTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiTimeTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiRealTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiStructTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiUnionTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiBitTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiLogicTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiArrayTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiVoidTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiTypespecMember); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiDistItem); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiAliasStmt); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiThread); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiMethodFuncCall); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiMethodTaskCall); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiClockingBlock); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiClockingIODecl); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiClassDefn); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiConstraint); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiConstraintOrdering); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiPropertyDecl); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiPropertySpec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiPropertyExpr); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiMulticlockSequenceExpr); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiClockedSeq); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiPropertyInst); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiSequenceDecl); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiCaseProperty); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiSequenceInst); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiImmediateAssert); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiReturn); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiAnyPattern); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiTaggedPattern); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiStructPattern); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiDoWhile); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiOrderedWait); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiWaitFork); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiDisableFork); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiExpectStmt); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiForeachStmt); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiFinal); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiExtends); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiDistribution); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiSeqFormalDecl); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiEnumNet); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiIntegerNet); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiTimeNet); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiStructNet); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiBreak); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiContinue); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiAssert); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiAssume); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiCover); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiDisableCondition); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiClockingEvent); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiReturnStmt); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiPackedArrayTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiPackedArrayNet); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiImmediateAssume); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiImmediateCover); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiSequenceTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiPropertyTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiEventTypespec); + SELF_CHECK_ENUM_STR(strFromVpiObjType, vpiPropFormalDecl); SELF_CHECK_ENUM_STR(strFromVpiMethod, vpiCondition); SELF_CHECK_ENUM_STR(strFromVpiMethod, vpiStmt); @@ -1734,7 +1946,8 @@ bool vl_check_format(const VerilatedVar* varp, const p_vpi_value valuep, const c case VLVT_UINT64: case VLVT_WDATA: return status; case VLVT_STRING: - if (isGetValue) { + // string parameter values can't be changed + if (isGetValue || !varp->isParam()) { return status; } else { status = false; @@ -1749,6 +1962,11 @@ bool vl_check_format(const VerilatedVar* varp, const p_vpi_value valuep, const c case VLVT_UINT32: return status; default: status = false; } + } else if (valuep->format == vpiRealVal) { + switch (varp->vltype()) { + case VLVT_REAL: return status; + default: status = false; + } } else if (valuep->format == vpiSuppressVal) { return status; } else { @@ -1766,6 +1984,8 @@ void vl_get_value(const VerilatedVar* varp, void* varDatap, p_vpi_value valuep, static thread_local char t_outStr[VL_VALUE_STRING_MAX_WORDS * VL_EDATASIZE + 1]; // cppcheck-suppress variableScope static const thread_local int t_outStrSz = sizeof(t_outStr) - 1; + // string data type is dynamic and may vary in size during simulation + static thread_local std::string t_outDynamicStr; // We used to presume vpiValue.format = vpiIntVal or if single bit vpiScalarVal // This may cause backward compatibility issues with older code. if (valuep->format == vpiVectorVal) { @@ -1918,8 +2138,14 @@ void vl_get_value(const VerilatedVar* varp, void* varDatap, p_vpi_value valuep, return; } else if (valuep->format == vpiStringVal) { if (varp->vltype() == VLVT_STRING) { - valuep->value.str = reinterpret_cast(varDatap); - return; + if (varp->isParam()) { + valuep->value.str = reinterpret_cast(varDatap); + return; + } else { + t_outDynamicStr = *(reinterpret_cast(varDatap)); + valuep->value.str = const_cast(t_outDynamicStr.c_str()); + return; + } } else { valuep->value.str = t_outStr; int bytes = VL_BYTES_I(varp->packed().elements()); @@ -1954,6 +2180,9 @@ void vl_get_value(const VerilatedVar* varp, void* varDatap, p_vpi_value valuep, valuep->value.integer = *(reinterpret_cast(varDatap)); return; } + } else if (valuep->format == vpiRealVal) { + valuep->value.real = *(reinterpret_cast(varDatap)); + return; } else if (valuep->format == vpiSuppressVal) { return; } @@ -2171,12 +2400,17 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value valuep, p_vpi_time /*time_ datap[(chars - 1) >> 1] &= vop->mask_byte((chars - 1) >> 1); return object; } else if (valuep->format == vpiStringVal) { - const int bytes = VL_BYTES_I(vop->varp()->packed().elements()); - const int len = std::strlen(valuep->value.str); - CData* const datap = (reinterpret_cast(vop->varDatap())); - for (int i = 0; i < bytes; ++i) { - // prepend with 0 values before placing string the least significant bytes - datap[i] = (i < len) ? valuep->value.str[len - i - 1] : 0; + if (vop->varp()->vltype() == VLVT_STRING) { + *(reinterpret_cast(vop->varDatap())) = valuep->value.str; + return object; + } else { + const int bytes = VL_BYTES_I(vop->varp()->packed().elements()); + const int len = std::strlen(valuep->value.str); + CData* const datap = (reinterpret_cast(vop->varDatap())); + for (int i = 0; i < bytes; ++i) { + // prepend with 0 values before placing string the least significant bytes + datap[i] = (i < len) ? valuep->value.str[len - i - 1] : 0; + } } return object; } else if (valuep->format == vpiIntVal) { @@ -2190,6 +2424,11 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value valuep, p_vpi_time /*time_ *(reinterpret_cast(vop->varDatap())) = vop->mask() & valuep->value.integer; return object; } + } else if (valuep->format == vpiRealVal) { + if (vop->varp()->vltype() == VLVT_REAL) { + *(reinterpret_cast(vop->varDatap())) = valuep->value.real; + return object; + } } VL_VPI_ERROR_(__FILE__, __LINE__, "%s: Unsupported format (%s) as requested for %s", __func__, VerilatedVpiError::strFromVpiVal(valuep->format), vop->fullname()); diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 09dd075c2e..3de6c95710 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -466,6 +466,8 @@ string AstVar::vlEnumType() const { return "VLVT_PTR"; } else if (strtype) { arg += "VLVT_STRING"; + } else if (isDouble()) { + arg += "VLVT_REAL"; } else if (widthMin() <= 8) { arg += "VLVT_UINT8"; } else if (widthMin() <= 16) { diff --git a/test_regress/t/TestCheck.h b/test_regress/t/TestCheck.h index c9b054b6c6..17a25accbc 100644 --- a/test_regress/t/TestCheck.h +++ b/test_regress/t/TestCheck.h @@ -72,6 +72,16 @@ static const bool verbose = false; } \ } while (0) +#define TEST_CHECK_REAL_EQ(got, exp, delta) \ + do { \ + if (std::fabs(got - exp) > delta) { \ + std::cout << std::dec << "%Error: " << __FILE__ << ":" << __LINE__ << std::showpoint \ + << ": GOT=" << (got) << " EXP=" << (exp) << " +/- " << (delta) \ + << std::endl; \ + ++errors; \ + } \ + } while (0) + //====================================================================== #define TEST_VERBOSE_PRINTF(format, ...) \ diff --git a/test_regress/t/TestSimulator.h b/test_regress/t/TestSimulator.h index 0f36594406..b7c1acb14b 100644 --- a/test_regress/t/TestSimulator.h +++ b/test_regress/t/TestSimulator.h @@ -31,7 +31,7 @@ class TestSimulator { vpi_get_vlog_info(&m_info); if (0 == std::strcmp(m_info.product, "Verilator")) { m_simulators.verilator = true; - } else if (0 == std::strcmp(m_info.product, "Verilator")) { + } else if (0 == std::strcmp(m_info.product, "Icarus Verilog")) { m_simulators.icarus = true; } else if (0 == strncmp(m_info.product, "Chronologic Simulation VCS", @@ -64,7 +64,7 @@ class TestSimulator { static bool has_get_scalar() { return !simulators().icarus; } // return test level scope static const char* top() { - if (simulators().verilator) { + if (simulators().verilator || simulators().icarus) { return "t"; } else { return "top.t"; diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index 0281fb367c..f7db91da23 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -11,7 +11,7 @@ #ifdef IS_VPI -#include "vpi_user.h" +#include "sv_vpi_user.h" #else @@ -31,12 +31,14 @@ #endif +#include #include #include #include #include // These require the above. Comment prevents clang-format moving them +#include "TestCheck.h" #include "TestSimulator.h" #include "TestVpi.h" @@ -56,12 +58,6 @@ unsigned int callback_count_strs_max = 500; //====================================================================== -#ifdef TEST_VERBOSE -bool verbose = true; -#else -bool verbose = false; -#endif - #define CHECK_RESULT_VH(got, exp) \ if ((got) != (exp)) { \ printf("%%Error: %s:%d: GOT = %p EXP = %p\n", FILENM, __LINE__, (got), (exp)); \ @@ -379,7 +375,33 @@ int _mon_check_var() { CHECK_RESULT_CSTR(p, "vpiConstant"); } - return 0; + // non-integer variables + tmpValue.format = vpiRealVal; + { + TestVpiHandle vh101 = VPI_HANDLE("real1"); + CHECK_RESULT_NZ(vh101); + d = vpi_get(vpiType, vh101); + CHECK_RESULT(d, vpiRealVar); + vpi_get_value(vh101, &tmpValue); + TEST_CHECK_REAL_EQ(tmpValue.value.real, 1.0, 0.0005); + p = vpi_get_str(vpiType, vh101); + CHECK_RESULT_CSTR(p, "vpiRealVar"); + } + + // string variable + tmpValue.format = vpiStringVal; + { + TestVpiHandle vh101 = VPI_HANDLE("str1"); + CHECK_RESULT_NZ(vh101); + d = vpi_get(vpiType, vh101); + CHECK_RESULT(d, vpiStringVar); + vpi_get_value(vh101, &tmpValue); + CHECK_RESULT_CSTR(tmpValue.value.str, "hello"); + p = vpi_get_str(vpiType, vh101); + CHECK_RESULT_CSTR(p, "vpiStringVar"); + } + + return errors; } int _mon_check_varlist() { @@ -443,7 +465,33 @@ int _mon_check_getput() { vpi_get_value(vh2, &v); CHECK_RESULT(v.value.integer, 1); - return 0; + // real + TestVpiHandle vh3 = VPI_HANDLE("real1"); + CHECK_RESULT_NZ(vh3); + v.format = vpiRealVal; + vpi_get_value(vh3, &v); + TEST_CHECK_REAL_EQ(v.value.real, 1.0, 0.0005); + + v.value.real = 123456.789; + vpi_put_value(vh3, &v, &t, vpiNoDelay); + v.value.real = 0.0f; + vpi_get_value(vh3, &v); + TEST_CHECK_REAL_EQ(v.value.real, 123456.789, 0.0005); + + // string + TestVpiHandle vh4 = VPI_HANDLE("str1"); + CHECK_RESULT_NZ(vh4); + v.format = vpiStringVal; + vpi_get_value(vh4, &v); + CHECK_RESULT_CSTR(v.value.str, "hello"); + + v.value.str = const_cast("something a lot longer than hello"); + vpi_put_value(vh4, &v, &t, vpiNoDelay); + v.value.str = 0; + vpi_get_value(vh4, &v); + TEST_CHECK_CSTR(v.value.str, "something a lot longer than hello"); + + return errors; } int _mon_check_var_long_name() { diff --git a/test_regress/t/t_vpi_var.v b/test_regress/t/t_vpi_var.v index 80188af113..495abb1f51 100644 --- a/test_regress/t/t_vpi_var.v +++ b/test_regress/t/t_vpi_var.v @@ -45,6 +45,9 @@ extern "C" int mon_check(); integer status; + real real1 /*verilator public_flat_rw */; + string str1 /*verilator public_flat_rw */; + sub sub(); // Test loop @@ -57,6 +60,10 @@ extern "C" int mon_check(); text_word = "Word"; text_long = "Long64b"; text = "Verilog Test module"; + + real1 = 1.0; + str1 = "hello"; + `ifdef VERILATOR status = $c32("mon_check()"); `endif @@ -79,6 +86,8 @@ extern "C" int mon_check(); if (text_word != "Tree") $stop; if (text_long != "44Four44") $stop; if (text != "lorem ipsum") $stop; + if (str1 != "something a lot longer than hello") $stop; + if (real1 > 123456.7895 || real1 < 123456.7885 ) $stop; end always @(posedge clk) begin diff --git a/test_regress/t/t_vpi_var2.v b/test_regress/t/t_vpi_var2.v index dc04a1c7fb..6726f7a9be 100644 --- a/test_regress/t/t_vpi_var2.v +++ b/test_regress/t/t_vpi_var2.v @@ -60,6 +60,11 @@ extern "C" int mon_check(); /*verilator public_off*/ integer status; +/*verilator public_flat_rw_on*/ + real real1; + string str1; +/*verilator public_off*/ + sub sub(); // Test loop @@ -72,6 +77,10 @@ extern "C" int mon_check(); text_word = "Word"; text_long = "Long64b"; text = "Verilog Test module"; + + real1 = 1.0; + str1 = "hello"; + `ifdef VERILATOR status = $c32("mon_check()"); `endif @@ -94,6 +103,8 @@ extern "C" int mon_check(); if (text_word != "Tree") $stop; if (text_long != "44Four44") $stop; if (text != "lorem ipsum") $stop; + if (str1 != "something a lot longer than hello") $stop; + if (real1 > 123456.7895 || real1 < 123456.7885 ) $stop; end always @(posedge clk) begin