diff --git a/docs/guide/connecting.rst b/docs/guide/connecting.rst index 724c2938b9..27c2e57a54 100644 --- a/docs/guide/connecting.rst +++ b/docs/guide/connecting.rst @@ -413,10 +413,6 @@ and it can be cleared with :code:`VerilatedVpi::clearEvalNeeded()`. Used togeth it is possible to skip :code:`eval()` calls if no model state has been changed since the last :code:`eval()`. -Any data written via :code:`vpi_put_value` with :code:`vpiInertialDelay` will -be deferred for later. These delayed values can be flushed to the model with -:code:`VerilatedVpi::doInertialPuts()`. - .. _VPI Example: diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 2f85565309..fd0914bfeb 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -636,146 +636,6 @@ class VerilatedVpiCbHolder final { void invalidate() { m_id = 0; } }; -class VerilatedVpiPutHolder final { - VerilatedVpioVar m_var; - s_vpi_value m_value; - union Storage { - char init = 0; // to ensure trivial constructor - std::string str; - std::vector vec; - ~Storage() noexcept {/* handled by VerilatedVpiPutHolder */}; - } m_storage{}; - -public: - VerilatedVpiPutHolder(const VerilatedVpioVar* vop, p_vpi_value valuep) - : m_var{vop} { - m_value.format = valuep->format; - switch (valuep->format) { - case vpiBinStrVal: // FALLTHRU - case vpiOctStrVal: // FALLTHRU - case vpiDecStrVal: // FALLTHRU - case vpiHexStrVal: // FALLTHRU - case vpiStringVal: { - new (&m_storage.str) std::string{valuep->value.str}; - m_value.value.str = const_cast(m_storage.str.c_str()); - break; - } - case vpiScalarVal: { - m_value.value.scalar = valuep->value.scalar; - break; - } - case vpiIntVal: { - m_value.value.integer = valuep->value.integer; - break; - } - case vpiRealVal: { - m_value.value.real = valuep->value.real; - break; - } - case vpiVectorVal: { - size_t words = 0; - switch (vop->varp()->vltype()) { - case VLVT_UINT8: - case VLVT_UINT16: - case VLVT_UINT32: { - words = 1; - break; - } - case VLVT_UINT64: { - words = 2; - break; - } - case VLVT_WDATA: { - words = VL_WORDS_I(vop->varp()->packed().elements()); - break; - } - default: break; - } - new (&m_storage.vec) - std::vector{valuep->value.vector, &valuep->value.vector[words]}; - m_value.value.vector = m_storage.vec.data(); - break; - } - } - } - - VerilatedVpiPutHolder(VerilatedVpiPutHolder const& o) - : m_var{o.m_var} - , m_value{o.m_value} { - switch (m_value.format) { - case vpiBinStrVal: // FALLTHRU - case vpiOctStrVal: // FALLTHRU - case vpiDecStrVal: // FALLTHRU - case vpiHexStrVal: // FALLTHRU - case vpiStringVal: { - new (&m_storage.str) std::string{o.m_storage.str}; - break; - } - case vpiVectorVal: { - new (&m_storage.vec) std::vector{o.m_storage.vec}; - break; - } - } - } - - VerilatedVpiPutHolder(VerilatedVpiPutHolder&& o) noexcept - : m_var{std::move(o.m_var)} - , m_value{std::move(o.m_value)} { - switch (m_value.format) { - case vpiBinStrVal: // FALLTHRU - case vpiOctStrVal: // FALLTHRU - case vpiDecStrVal: // FALLTHRU - case vpiHexStrVal: // FALLTHRU - case vpiStringVal: { - new (&m_storage.str) std::string{std::move(o.m_storage.str)}; - break; - } - case vpiVectorVal: { - new (&m_storage.vec) std::vector{std::move(o.m_storage.vec)}; - break; - } - } - } - - ~VerilatedVpiPutHolder() noexcept { - switch (m_value.format) { - case vpiBinStrVal: // FALLTHRU - case vpiOctStrVal: // FALLTHRU - case vpiDecStrVal: // FALLTHRU - case vpiHexStrVal: // FALLTHRU - case vpiStringVal: m_storage.str.~basic_string(); break; - case vpiVectorVal: m_storage.vec.~vector(); break; - } - } - - VerilatedVpioVar* varp() { return &m_var; } - p_vpi_value valuep() { return &m_value; } - - static bool canInertialDelay(p_vpi_value valuep) { - switch (valuep->format) { - case vpiBinStrVal: // FALLTHRU - case vpiOctStrVal: // FALLTHRU - case vpiDecStrVal: // FALLTHRU - case vpiHexStrVal: // FALLTHRU - case vpiStringVal: { - if (VL_UNLIKELY(!valuep->value.str)) return false; - break; - } - case vpiScalarVal: // FALLTHRU - case vpiIntVal: // FALLTHRU - case vpiRealVal: break; - case vpiVectorVal: { - if (VL_UNLIKELY(!valuep->value.vector)) return false; - break; - } - default: { - return false; - } - } - return true; - } -}; - struct VerilatedVpiTimedCbsCmp final { // Ordering sets keyed by time, then callback unique id bool operator()(const std::pair& a, @@ -798,7 +658,6 @@ class VerilatedVpiImp final { std::array m_cbCurrentLists; VpioFutureCbs m_futureCbs; // Time based callbacks for future timestamps VpioFutureCbs m_nextCbs; // cbNextSimTime callbacks - std::list m_inertialPuts; // Pending vpi puts due to vpiInertialDelay VerilatedVpiError* m_errorInfop = nullptr; // Container for vpi error info VerilatedAssertOneThread m_assertOne; // Assert only called from single thread uint64_t m_nextCallbackId = 1; // Id to identify callback @@ -964,17 +823,8 @@ class VerilatedVpiImp final { } static void dumpCbs() VL_MT_UNSAFE_ONE; static VerilatedVpiError* error_info() VL_MT_UNSAFE_ONE; // getter for vpi error info - static bool evalNeeded() { return s().m_evalNeeded; } static void evalNeeded(bool evalNeeded) { s().m_evalNeeded = evalNeeded; } - static void inertialDelay(const VerilatedVpioVar* vop, p_vpi_value valuep) { - s().m_inertialPuts.emplace_back(vop, valuep); - } - static void doInertialPuts() { - for (auto& it : s().m_inertialPuts) { - vpi_put_value(it.varp()->castVpiHandle(), it.valuep(), nullptr, vpiNoDelay); - } - s().m_inertialPuts.clear(); - } + static bool evalNeeded() { return s().m_evalNeeded; } }; //====================================================================== @@ -1084,8 +934,6 @@ PLI_INT32 VerilatedVpioReasonCb::dovpi_remove_cb() { void VerilatedVpi::clearEvalNeeded() VL_MT_UNSAFE_ONE { VerilatedVpiImp::evalNeeded(false); } bool VerilatedVpi::evalNeeded() VL_MT_UNSAFE_ONE { return VerilatedVpiImp::evalNeeded(); } -void VerilatedVpi::doInertialPuts() VL_MT_UNSAFE_ONE { VerilatedVpiImp::doInertialPuts(); } - //====================================================================== // VerilatedVpiImp implementation @@ -2572,7 +2420,7 @@ void vpi_get_value(vpiHandle object, p_vpi_value valuep) { } vpiHandle vpi_put_value(vpiHandle object, p_vpi_value valuep, p_vpi_time /*time_p*/, - PLI_INT32 flags) { + PLI_INT32 /*flags*/) { VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_put_value %p %p\n", object, valuep);); VerilatedVpiImp::assertOneCheck(); VL_VPI_ERROR_RESET_(); @@ -2580,19 +2428,7 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value valuep, p_vpi_time /*time_ VL_VPI_WARNING_(__FILE__, __LINE__, "Ignoring vpi_put_value with nullptr value pointer"); return nullptr; } - PLI_INT32 delay_mode = flags & 0xfff; if (const VerilatedVpioVar* const vop = VerilatedVpioVar::castp(object)) { - if (delay_mode == vpiInertialDelay) { - if (!VerilatedVpiPutHolder::canInertialDelay(valuep)) { - VL_VPI_WARNING_( - __FILE__, __LINE__, - "%s: Unsupported p_vpi_value as requested for '%s' with vpiInertialDelay", - __func__, vop->fullname()); - return nullptr; - } - VerilatedVpiImp::inertialDelay(vop, valuep); - return object; - } VL_DEBUG_IF_PLI( VL_DBG_MSGF("- vpi: vpi_put_value name=%s fmt=%d vali=%d\n", vop->fullname(), valuep->format, valuep->value.integer); diff --git a/include/verilated_vpi.h b/include/verilated_vpi.h index 51727cb016..3a3f24999e 100644 --- a/include/verilated_vpi.h +++ b/include/verilated_vpi.h @@ -62,8 +62,6 @@ class VerilatedVpi final { static bool evalNeeded() VL_MT_UNSAFE_ONE; /// Clears VPI dirty state (see evalNeeded()) static void clearEvalNeeded() VL_MT_UNSAFE_ONE; - /// Perform inertially delayed puts - static void doInertialPuts() VL_MT_UNSAFE_ONE; // Self test, for internal use only static void selfTest() VL_MT_UNSAFE_ONE; diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index db721c306f..9ea21c4a16 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -676,49 +676,6 @@ int _mon_check_quad() { return 0; } -int _mon_check_delayed() { - TestVpiHandle vh = VPI_HANDLE("delayed"); - CHECK_RESULT_NZ(vh); - - s_vpi_time t; - t.type = vpiSimTime; - t.high = 0; - t.low = 0; - - s_vpi_value v; - v.format = vpiIntVal; - v.value.integer = 123; - vpi_put_value(vh, &v, &t, vpiInertialDelay); - CHECK_RESULT_Z(vpi_chk_error(nullptr)); - vpi_get_value(vh, &v); - CHECK_RESULT(v.value.integer, 0); - - TestVpiHandle vhMem = VPI_HANDLE("delayed_mem"); - CHECK_RESULT_NZ(vhMem); - TestVpiHandle vhMemWord = vpi_handle_by_index(vhMem, 7); - CHECK_RESULT_NZ(vhMemWord); - v.value.integer = 456; - vpi_put_value(vhMemWord, &v, &t, vpiInertialDelay); - CHECK_RESULT_Z(vpi_chk_error(nullptr)); - - // test unsupported vpiInertialDelay cases - v.format = vpiStringVal; - v.value.str = nullptr; - vpi_put_value(vh, &v, &t, vpiInertialDelay); - CHECK_RESULT_NZ(vpi_chk_error(nullptr)); - - v.format = vpiVectorVal; - v.value.vector = nullptr; - vpi_put_value(vh, &v, &t, vpiInertialDelay); - CHECK_RESULT_NZ(vpi_chk_error(nullptr)); - - v.format = vpiObjTypeVal; - vpi_put_value(vh, &v, &t, vpiInertialDelay); - CHECK_RESULT_NZ(vpi_chk_error(nullptr)); - - return 0; -} - int _mon_check_string() { static struct { const char* name; @@ -927,8 +884,6 @@ extern "C" int mon_check() { if (int status = _mon_check_string()) return status; if (int status = _mon_check_putget_str(NULL)) return status; if (int status = _mon_check_vlog_info()) return status; - if (int status = _mon_check_delayed()) return status; - if (int status = _mon_check_too_big()) return status; #ifndef IS_VPI VerilatedVpi::selfTest(); #endif @@ -998,7 +953,6 @@ int main(int argc, char** argv) { while (vl_time_stamp64() < sim_time && !contextp->gotFinish()) { main_time += 1; - VerilatedVpi::doInertialPuts(); topp->eval(); VerilatedVpi::callValueCbs(); topp->clk = !topp->clk; diff --git a/test_regress/t/t_vpi_var.v b/test_regress/t/t_vpi_var.v index d93196cc9f..c4666f7f9f 100644 --- a/test_regress/t/t_vpi_var.v +++ b/test_regress/t/t_vpi_var.v @@ -41,8 +41,6 @@ extern "C" int mon_check(); reg [31:0] count /*verilator public_flat_rd */; reg [31:0] half_count /*verilator public_flat_rd */; - reg [31:0] delayed /*verilator public_flat_rw */; - reg [31:0] delayed_mem [16] /*verilator public_flat_rw */; reg [7:0] text_byte /*verilator public_flat_rw @(posedge clk) */; reg [15:0] text_half /*verilator public_flat_rw @(posedge clk) */; @@ -64,7 +62,6 @@ extern "C" int mon_check(); // Test loop initial begin count = 0; - delayed = 0; onebit = 1'b0; fourthreetwoone[3] = 0; // stop icarus optimizing away text_byte = "B"; @@ -109,8 +106,6 @@ extern "C" int mon_check(); half_count <= half_count + 2; if (count == 1000) begin - if (delayed != 123) $stop; - if (delayed_mem[7] != 456) $stop; $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_vpi_var2.v b/test_regress/t/t_vpi_var2.v index 0c0019ddf2..5912b47946 100644 --- a/test_regress/t/t_vpi_var2.v +++ b/test_regress/t/t_vpi_var2.v @@ -54,10 +54,6 @@ extern "C" int mon_check(); /*verilator public_flat_rd_on*/ reg [31:0] count; reg [31:0] half_count; -/*verilator public_off*/ -/*verilator public_flat_rw_on*/ - reg [31:0] delayed; - reg [31:0] delayed_mem [16]; /*verilator public_off*/ reg invisible2; @@ -82,7 +78,6 @@ extern "C" int mon_check(); // Test loop initial begin count = 0; - delayed = 0; onebit = 1'b0; fourthreetwoone[3] = 0; // stop icarus optimizing away text_byte = "B"; @@ -127,8 +122,6 @@ extern "C" int mon_check(); half_count <= half_count + 2; if (count == 1000) begin - if (delayed != 123) $stop; - if (delayed_mem[7] != 456) $stop; $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_vpi_var3.v b/test_regress/t/t_vpi_var3.v index a6422b8c2c..821ed8a307 100644 --- a/test_regress/t/t_vpi_var3.v +++ b/test_regress/t/t_vpi_var3.v @@ -41,8 +41,6 @@ extern "C" int mon_check(); reg [31:0] count; reg [31:0] half_count; - reg [31:0] delayed; - reg [31:0] delayed_mem [16]; reg [7:0] text_byte; reg [15:0] text_half; @@ -62,7 +60,6 @@ extern "C" int mon_check(); // Test loop initial begin count = 0; - delayed = 0; onebit = 1'b0; fourthreetwoone[3] = 0; // stop icarus optimizing away text_byte = "B"; @@ -107,8 +104,6 @@ extern "C" int mon_check(); half_count <= half_count + 2; if (count == 1000) begin - if (delayed != 123) $stop; - if (delayed_mem[7] != 456) $stop; $write("*-* All Finished *-*\n"); $finish; end