From 30546afdabad094eb504b9e0743846ecd62626ae Mon Sep 17 00:00:00 2001 From: Marlon James Date: Sat, 12 Dec 2020 05:11:08 -0800 Subject: [PATCH] Fix VPI range iterator null return (#2691) * Test that range iterator exhausts after 1 dimension * Separate range iterator from range object Range iterators should return NULL after all ranges have been returned --- include/verilated_vpi.cpp | 29 +++++++++++++++++++---------- test_regress/t/t_vpi_memory.cpp | 3 +++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index fe730dbfa..607a85610 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -167,7 +167,6 @@ public: class VerilatedVpioRange final : public VerilatedVpio { const VerilatedRange* m_range; - vlsint32_t m_iteration = 0; public: explicit VerilatedVpioRange(const VerilatedRange* range) @@ -179,15 +178,25 @@ public: virtual vluint32_t type() const override { return vpiRange; } virtual vluint32_t size() const override { return m_range->elements(); } virtual const VerilatedRange* rangep() const override { return m_range; } - int iteration() const { return m_iteration; } - void iterationInc() { ++m_iteration; } +}; + +class VerilatedVpioRangeIter final : public VerilatedVpio { + // Only supports 1 dimension + const VerilatedRange* m_range; + bool m_done = false; + +public: + explicit VerilatedVpioRangeIter(const VerilatedRange* range) + : m_range{range} {} + virtual ~VerilatedVpioRangeIter() override = default; + static VerilatedVpioRangeIter* castp(vpiHandle h) { + return dynamic_cast(reinterpret_cast(h)); + } + virtual vluint32_t type() const override { return vpiIterator; } virtual vpiHandle dovpi_scan() override { - if (!iteration()) { - VerilatedVpioRange* nextp = new VerilatedVpioRange(*this); - nextp->iterationInc(); - return ((nextp)->castVpiHandle()); - } - return nullptr; // End of list - only one deep + if (m_done) return nullptr; + m_done = true; + return ((new VerilatedVpioRange(m_range))->castVpiHandle()); } }; @@ -1249,7 +1258,7 @@ vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle object) { VerilatedVpiError::strFromVpiMethod(type), vop->fullname(), vop->varp()->dims()); } - return ((new VerilatedVpioRange(vop->rangep()))->castVpiHandle()); + return ((new VerilatedVpioRangeIter(vop->rangep()))->castVpiHandle()); } case vpiReg: { VerilatedVpioScope* vop = VerilatedVpioScope::castp(object); diff --git a/test_regress/t/t_vpi_memory.cpp b/test_regress/t/t_vpi_memory.cpp index 6cfaebdaf..374a166e8 100644 --- a/test_regress/t/t_vpi_memory.cpp +++ b/test_regress/t/t_vpi_memory.cpp @@ -174,6 +174,9 @@ int _mon_check_memory() { CHECK_RESULT_NZ(side_h); vpi_get_value(side_h, &value); CHECK_RESULT(value.value.integer, 1); + // iterator should exhaust after 1 dimension + lcl_h = vpi_scan(iter_h); + CHECK_RESULT(lcl_h, 0); // check writing to vpiConstant vpi_put_value(side_h, &value, NULL, vpiNoDelay);