From f44629527474d5e598e4c2a33f70cbf606dc0de8 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Wed, 21 Apr 2021 13:46:13 -0400 Subject: [PATCH] Public interface params (#2901) --- include/verilated_vpi.cpp | 80 +++++++++++++++++++----------------- src/V3LinkParse.cpp | 2 + test_regress/t/t_vpi_get.cpp | 7 +++- test_regress/t/t_vpi_get.v | 13 +++++- 4 files changed, 61 insertions(+), 41 deletions(-) diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 01412094f..c3346429e 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -171,23 +171,32 @@ public: vlsint32_t num() const { return m_num; } }; -class VerilatedVpioParam final : public VerilatedVpio { - const VerilatedVar* m_varp; - const VerilatedScope* m_scopep; +class VerilatedVpioVarBase VL_NOT_FINAL : public VerilatedVpio { +protected: + const VerilatedVar* m_varp = nullptr; + const VerilatedScope* m_scopep = nullptr; + const VerilatedRange& get_range() const { + // Determine number of dimensions and return outermost + return (m_varp->dims() > 1) ? m_varp->unpacked() : m_varp->packed(); + } public: - VerilatedVpioParam(const VerilatedVar* varp, const VerilatedScope* scopep) + VerilatedVpioVarBase(const VerilatedVar* varp, const VerilatedScope* scopep) : m_varp{varp} , m_scopep{scopep} {} - virtual ~VerilatedVpioParam() override = default; - - static VerilatedVpioParam* castp(vpiHandle h) { - return dynamic_cast(reinterpret_cast(h)); + explicit VerilatedVpioVarBase(const VerilatedVpioVarBase* varp) { + if (varp) { + m_varp = varp->m_varp; + m_scopep = varp->m_scopep; + } + } + static VerilatedVpioVarBase* castp(vpiHandle h) { + return dynamic_cast(reinterpret_cast(h)); } - virtual vluint32_t type() const override { return vpiParameter; } const VerilatedVar* varp() const { return m_varp; } - void* varDatap() const { return m_varp->datap(); } const VerilatedScope* scopep() const { return m_scopep; } + virtual vluint32_t size() const override { return get_range().elements(); } + virtual const VerilatedRange* rangep() const override { return &get_range(); } virtual const char* name() const override { return m_varp->name(); } virtual const char* fullname() const override { static VL_THREAD_LOCAL std::string t_out; @@ -196,6 +205,19 @@ public: } }; +class VerilatedVpioParam final : public VerilatedVpioVarBase { +public: + VerilatedVpioParam(const VerilatedVar* varp, const VerilatedScope* scopep) + : VerilatedVpioVarBase(varp, scopep) {} + virtual ~VerilatedVpioParam() override = default; + + static VerilatedVpioParam* castp(vpiHandle h) { + return dynamic_cast(reinterpret_cast(h)); + } + virtual vluint32_t type() const override { return vpiParameter; } + void* varDatap() const { return m_varp->datap(); } +}; + class VerilatedVpioRange final : public VerilatedVpio { const VerilatedRange* m_range; @@ -251,9 +273,7 @@ public: virtual const char* fullname() const override { return m_scopep->name(); } }; -class VerilatedVpioVar VL_NOT_FINAL : public VerilatedVpio { - const VerilatedVar* m_varp = nullptr; - const VerilatedScope* m_scopep = nullptr; +class VerilatedVpioVar VL_NOT_FINAL : public VerilatedVpioVarBase { vluint8_t* m_prevDatap = nullptr; // Previous value of data, for cbValueChange union { vluint8_t u8[4]; @@ -263,23 +283,17 @@ class VerilatedVpioVar VL_NOT_FINAL : public VerilatedVpio { protected: void* m_varDatap = nullptr; // varp()->datap() adjusted for array entries vlsint32_t m_index = 0; - const VerilatedRange& get_range() const { - // Determine number of dimensions and return outermost - return (m_varp->dims() > 1) ? m_varp->unpacked() : m_varp->packed(); - } public: VerilatedVpioVar(const VerilatedVar* varp, const VerilatedScope* scopep) - : m_varp{varp} - , m_scopep{scopep} { + : VerilatedVpioVarBase(varp, scopep) { m_mask.u32 = VL_MASK_I(varp->packed().elements()); m_entSize = varp->entSize(); m_varDatap = varp->datap(); } - explicit VerilatedVpioVar(const VerilatedVpioVar* varp) { + explicit VerilatedVpioVar(const VerilatedVpioVar* varp) + : VerilatedVpioVarBase(varp) { if (varp) { - m_varp = varp->m_varp; - m_scopep = varp->m_scopep; m_mask.u32 = varp->m_mask.u32; m_entSize = varp->m_entSize; m_varDatap = varp->m_varDatap; @@ -295,8 +309,6 @@ public: static VerilatedVpioVar* castp(vpiHandle h) { return dynamic_cast(reinterpret_cast(h)); } - const VerilatedVar* varp() const { return m_varp; } - const VerilatedScope* scopep() const { return m_scopep; } vluint32_t mask() const { return m_mask.u32; } vluint8_t mask_byte(int idx) { return m_mask.u8[idx & 3]; } vluint32_t entSize() const { return m_entSize; } @@ -304,14 +316,6 @@ public: virtual vluint32_t type() const override { return (varp()->dims() > 1) ? vpiMemory : vpiReg; // but might be wire, logic } - virtual vluint32_t size() const override { return get_range().elements(); } - virtual const VerilatedRange* rangep() const override { return &get_range(); } - virtual const char* name() const override { return m_varp->name(); } - virtual const char* fullname() const override { - static VL_THREAD_LOCAL std::string t_out; - t_out = std::string(m_scopep->name()) + "." + name(); - return t_out.c_str(); - } void* prevDatap() const { return m_prevDatap; } void* varDatap() const { return m_varDatap; } void createPrevDatap() { @@ -1433,7 +1437,7 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) { VL_VPI_ERROR_RESET_(); switch (type) { case vpiLeftRange: { - if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) { + if (VerilatedVpioVarBase* vop = VerilatedVpioVarBase::castp(object)) { if (VL_UNLIKELY(!vop->rangep())) return nullptr; return (new VerilatedVpioConst(vop->rangep()->left()))->castVpiHandle(); } else if (VerilatedVpioRange* vop = VerilatedVpioRange::castp(object)) { @@ -1446,7 +1450,7 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) { return nullptr; } case vpiRightRange: { - if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) { + if (VerilatedVpioVarBase* vop = VerilatedVpioVarBase::castp(object)) { if (VL_UNLIKELY(!vop->rangep())) return nullptr; return (new VerilatedVpioConst(vop->rangep()->right()))->castVpiHandle(); } else if (VerilatedVpioRange* vop = VerilatedVpioRange::castp(object)) { @@ -1464,7 +1468,7 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) { return (new VerilatedVpioConst(vop->index()))->castVpiHandle(); } case vpiScope: { - VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); + VerilatedVpioVarBase* vop = VerilatedVpioVarBase::castp(object); if (VL_UNLIKELY(!vop)) return nullptr; return (new VerilatedVpioScope(vop->scopep()))->castVpiHandle(); } @@ -1568,18 +1572,18 @@ PLI_INT32 vpi_get(PLI_INT32 property, vpiHandle object) { } case vpiDirection: { // By forthought, the directions already are vpi enumerated - VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); + VerilatedVpioVarBase* vop = VerilatedVpioVarBase::castp(object); if (VL_UNLIKELY(!vop)) return 0; return vop->varp()->vldir(); } case vpiScalar: // FALLTHRU case vpiVector: { - VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); + VerilatedVpioVarBase* vop = VerilatedVpioVarBase::castp(object); if (VL_UNLIKELY(!vop)) return 0; return (property == vpiVector) ^ (vop->varp()->dims() == 0); } case vpiSize: { - VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); + VerilatedVpioVarBase* vop = VerilatedVpioVarBase::castp(object); if (VL_UNLIKELY(!vop)) return 0; return vop->size(); } diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 73af3f7ca..7744e6bfb 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -218,6 +218,8 @@ private: if (v3Global.opt.publicFlatRW()) { switch (nodep->varType()) { case AstVarType::VAR: // FALLTHRU + case AstVarType::GPARAM: // FALLTHRU + case AstVarType::LPARAM: // FALLTHRU case AstVarType::PORT: // FALLTHRU case AstVarType::WIRE: nodep->sigUserRWPublic(true); break; default: break; diff --git a/test_regress/t/t_vpi_get.cpp b/test_regress/t/t_vpi_get.cpp index 5e7e2b83e..fa97e5095 100644 --- a/test_regress/t/t_vpi_get.cpp +++ b/test_regress/t/t_vpi_get.cpp @@ -163,18 +163,23 @@ int mon_check_props() { {"fourthreetwoone", {2, vpiNoDirection, 0, vpiMemory}, {2, vpiNoDirection, 0, vpiMemoryWord}}, + {"theint", {32, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}}, {"clk", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}}, {"testin", {16, vpiInput, 0, vpiPort}, {0, 0, 0, 0}}, {"testout", {24, vpiOutput, 0, vpiPort}, {0, 0, 0, 0}}, {"sub.subin", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}}, {"sub.subout", {1, vpiOutput, 1, vpiPort}, {0, 0, 0, 0}}, + {"sub.subparam", {32, vpiNoDirection, 0, vpiParameter}, {0, 0, 0, 0}}, + {"sub.the_intf.bytesig", {8, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}}, + {"sub.the_intf.param", {32, vpiNoDirection, 0, vpiParameter}, {0, 0, 0, 0}}, + {"sub.the_intf.lparam", {32, vpiNoDirection, 0, vpiParameter}, {0, 0, 0, 0}}, {"twobytwo", {2, vpiNoDirection, 0, vpiMemory}, {2, vpiNoDirection, 0, vpiMemoryWord}}, {NULL, {0, 0, 0, 0}, {0, 0, 0, 0}}}; struct params* value = values; while (value->signal) { TestVpiHandle h = VPI_HANDLE(value->signal); - CHECK_RESULT_NZ(h); TEST_MSG("%s\n", value->signal); + CHECK_RESULT_NZ(h); if (int status = _mon_check_props(h, value->attributes.size, value->attributes.direction, value->attributes.scalar, value->attributes.type)) return status; diff --git a/test_regress/t/t_vpi_get.v b/test_regress/t/t_vpi_get.v index fe22e9e95..b52f87282 100644 --- a/test_regress/t/t_vpi_get.v +++ b/test_regress/t/t_vpi_get.v @@ -22,6 +22,11 @@ import "DPI-C" function void dpi_print(input string somestring); `define PUBLIC_FLAT_RW `endif +interface intf #(parameter int param `PUBLIC_FLAT_RD = 7); + localparam int lparam `PUBLIC_FLAT_RD = param + 1; + logic [7:0] bytesig `PUBLIC_FLAT_RD; +endinterface + module t (/*AUTOARG*/ // Inputs input clk `PUBLIC_FLAT_RD, @@ -43,6 +48,7 @@ extern "C" int mon_check(); reg onetwo [1:2] `PUBLIC_FLAT_RW; reg [2:1] fourthreetwoone[4:3] `PUBLIC_FLAT_RW; reg [1:0] [1:0] twobytwo `PUBLIC_FLAT_RW; + int theint `PUBLIC_FLAT_RW; integer status; @@ -68,7 +74,7 @@ extern "C" int mon_check(); status = mon_check(); `endif if (status!=0) begin - $write("%%Error: t_vpi_var.cpp:%0d: C Test failed\n", status); + $write("%%Error: t_vpi_get.cpp:%0d: C Test failed\n", status); $stop; end $write("*-* All Finished *-*\n"); @@ -77,8 +83,11 @@ extern "C" int mon_check(); endmodule : t -module sub ( +module sub #( + parameter int subparam `PUBLIC_FLAT_RD = 2 +) ( input subin `PUBLIC_FLAT_RD, output subout `PUBLIC_FLAT_RD ); + intf the_intf(); endmodule : sub