From 2d86f1373e487abf90b799d527fe8dc5ae616e26 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 20 Feb 2026 05:39:38 -0500 Subject: [PATCH] Support vpiBitVar (#7107). Fixes #7107. --- include/verilated.h | 3 ++- include/verilated_sym_props.h | 1 + include/verilated_vpi.cpp | 5 +++-- src/V3EmitCSyms.cpp | 2 ++ test_regress/t/t_vpi_var.cpp | 15 +++++++++++++++ test_regress/t/t_vpi_var.v | 2 ++ test_regress/t/t_vpi_var2.v | 2 ++ test_regress/t/t_vpi_var3.v | 2 ++ 8 files changed, 29 insertions(+), 3 deletions(-) diff --git a/include/verilated.h b/include/verilated.h index 9dee17abf..5fbc6ddd8 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -157,7 +157,8 @@ enum VerilatedVarFlags { VLVF_DPI_CLAY = (1 << 10), // DPI compatible C standard layout VLVF_CONTINUOUSLY = (1 << 11), // Is continously assigned VLVF_FORCEABLE = (1 << 12), // Forceable - VLVF_SIGNED = (1 << 13) // Signed integer + VLVF_SIGNED = (1 << 13), // Signed integer + VLVF_BITVAR = (1 << 14) // Four state bit (vs two state logic) }; // IEEE 1800-2023 Table 20-6 diff --git a/include/verilated_sym_props.h b/include/verilated_sym_props.h index 9cc726e90..1cdd3a990 100644 --- a/include/verilated_sym_props.h +++ b/include/verilated_sym_props.h @@ -161,6 +161,7 @@ public: // DPI compatible C standard layout bool isDpiCLayout() const { return ((m_vlflags & VLVF_DPI_CLAY) != 0); } bool isSigned() const { return ((m_vlflags & VLVF_SIGNED) != 0); } + bool isBitVar() const { return ((m_vlflags & VLVF_BITVAR) != 0); } int udims() const VL_MT_SAFE { return m_unpacked.size(); } int pdims() const VL_MT_SAFE { return m_packed.size(); } int dims() const VL_MT_SAFE { return pdims() + udims(); } diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 029b7bd65..6511d3c86 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -421,11 +421,12 @@ public: return ret; } uint32_t type() const override { - uint32_t type = vpiReg; + uint32_t type; + // TODO have V3EmitCSyms.cpp put vpiType directly into constant table switch (varp()->vltype()) { case VLVT_REAL: type = vpiRealVar; break; case VLVT_STRING: type = vpiStringVar; break; - default: break; + default: type = varp()->isBitVar() ? vpiBitVar : vpiReg; break; } if (isIndexedDimUnpacked()) return vpiRegArray; diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 20c44a1dd..c7dee5e68 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -828,6 +828,8 @@ std::vector EmitCSyms::getSymCtorStmts() { stmt += ", "; stmt += varp->vlEnumDir(); // VLVD_IN etc if (varp->dtypep()->skipRefp()->isSigned()) stmt += "|VLVF_SIGNED"; + if (varp->dtypep()->skipRefp()->basicp()->keyword() == VBasicDTypeKwd::BIT) + stmt += "|VLVF_BITVAR"; stmt += ", "; stmt += std::to_string(udim); stmt += ", "; diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index a78321f06..4aa8ca21f 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -419,6 +419,21 @@ int _mon_check_var() { CHECK_RESULT(d, vpiUndefined); } + // other unsigned types + constexpr struct { + const char* name; + PLI_INT32 exp_type; + } uint_vars[] = { + // uvm_hdl_polling.v requires single bits return vpiBitVar + {"bit1", vpiBitVar}, + }; + for (const auto& s : uint_vars) { + TestVpiHandle vh101 = VPI_HANDLE(s.name); + CHECK_RESULT_NZ(vh101); + d = vpi_get(vpiType, vh101); + CHECK_RESULT(d, s.exp_type); + } + // other integer types tmpValue.format = vpiIntVal; constexpr struct { diff --git a/test_regress/t/t_vpi_var.v b/test_regress/t/t_vpi_var.v index 4feebc607..0adcdf638 100644 --- a/test_regress/t/t_vpi_var.v +++ b/test_regress/t/t_vpi_var.v @@ -54,6 +54,7 @@ extern "C" int mon_check(); integer status; + bit bit1 /*verilator public_flat_rw */; integer integer1 /*verilator public_flat_rw */; byte byte1 /*verilator public_flat_rw */; shortint short1 /*verilator public_flat_rw */; @@ -82,6 +83,7 @@ extern "C" int mon_check(); text = "Verilog Test module"; too_big = "some text"; + bit1 = 1; integer1 = 123; byte1 = 123; short1 = 123; diff --git a/test_regress/t/t_vpi_var2.v b/test_regress/t/t_vpi_var2.v index 99a46940e..bea0e11e8 100644 --- a/test_regress/t/t_vpi_var2.v +++ b/test_regress/t/t_vpi_var2.v @@ -73,6 +73,7 @@ extern "C" int mon_check(); integer status; /*verilator public_flat_rw_on*/ + bit bit1; integer integer1; byte byte1; shortint short1; @@ -99,6 +100,7 @@ extern "C" int mon_check(); text = "Verilog Test module"; too_big = "some text"; + bit1 = 1; integer1 = 123; byte1 = 123; short1 = 123; diff --git a/test_regress/t/t_vpi_var3.v b/test_regress/t/t_vpi_var3.v index 977828e73..0870059cd 100644 --- a/test_regress/t/t_vpi_var3.v +++ b/test_regress/t/t_vpi_var3.v @@ -54,6 +54,7 @@ extern "C" int mon_check(); integer status; + bit bit1; integer integer1; byte byte1; shortint short1; @@ -79,6 +80,7 @@ extern "C" int mon_check(); text = "Verilog Test module"; too_big = "some text"; + bit1 = 1; integer1 = 123; byte1 = 123; short1 = 123;