From 19cccd170ec546ee4e136e20012e9023f47bc8f5 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Fri, 10 May 2024 18:49:43 -0400 Subject: [PATCH] Fix vpiInertialDelay for memories (#5113) --- include/verilated_vpi.cpp | 12 ++++-------- test_regress/t/t_vpi_var.cpp | 8 ++++++++ test_regress/t/t_vpi_var.v | 2 ++ test_regress/t/t_vpi_var2.v | 2 ++ test_regress/t/t_vpi_var3.v | 2 ++ 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 5cb9992fd..cfa859cab 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -631,16 +631,14 @@ public: }; class VerilatedVpiPutHolder final { - const VerilatedVar* m_varp; - const VerilatedScope* m_scopep; + VerilatedVpioVar m_var; s_vpi_value m_value; std::string m_str; std::vector m_vector; public: VerilatedVpiPutHolder(const VerilatedVpioVar* vop, p_vpi_value valuep) - : m_varp(vop->varp()) - , m_scopep(vop->scopep()) { + : m_var(vop) { m_value.format = valuep->format; switch (valuep->format) { case vpiBinStrVal: @@ -691,8 +689,7 @@ public: } } - const VerilatedVar* varp() { return m_varp; } - const VerilatedScope* scopep() { return m_scopep; } + VerilatedVpioVar* varp() { return &m_var; } p_vpi_value valuep() { return &m_value; } static bool canInertialDelay(p_vpi_value valuep) { @@ -912,8 +909,7 @@ public: } static void doInertialPuts() { for (auto it : s().m_inertialPuts) { - VerilatedVpioVar vo(it.varp(), it.scopep()); - vpi_put_value(vo.castVpiHandle(), it.valuep(), nullptr, vpiNoDelay); + vpi_put_value(it.varp()->castVpiHandle(), it.valuep(), nullptr, vpiNoDelay); } s().m_inertialPuts.clear(); } diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index 9945868fa..8f4189271 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -700,6 +700,14 @@ int _mon_check_delayed() { 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; diff --git a/test_regress/t/t_vpi_var.v b/test_regress/t/t_vpi_var.v index 0e83708e7..8828b1776 100644 --- a/test_regress/t/t_vpi_var.v +++ b/test_regress/t/t_vpi_var.v @@ -42,6 +42,7 @@ 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) */; @@ -104,6 +105,7 @@ extern "C" int mon_check(); 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 ba9dcbb55..85b015766 100644 --- a/test_regress/t/t_vpi_var2.v +++ b/test_regress/t/t_vpi_var2.v @@ -57,6 +57,7 @@ extern "C" int mon_check(); /*verilator public_off*/ /*verilator public_flat_rw_on*/ reg [31:0] delayed; + reg [31:0] delayed_mem [16]; /*verilator public_off*/ reg invisible2; @@ -124,6 +125,7 @@ extern "C" int mon_check(); 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 f46518ed7..6e62d5c66 100644 --- a/test_regress/t/t_vpi_var3.v +++ b/test_regress/t/t_vpi_var3.v @@ -42,6 +42,7 @@ 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; @@ -104,6 +105,7 @@ extern "C" int mon_check(); if (count == 1000) begin if (delayed != 123) $stop; + if (delayed_mem[7] != 456) $stop; $write("*-* All Finished *-*\n"); $finish; end