Public interface params (#2901)

This commit is contained in:
Todd Strader 2021-04-21 13:46:13 -04:00 committed by GitHub
parent f450d51de1
commit f446295274
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 41 deletions

View File

@ -171,23 +171,32 @@ public:
vlsint32_t num() const { return m_num; } vlsint32_t num() const { return m_num; }
}; };
class VerilatedVpioParam final : public VerilatedVpio { class VerilatedVpioVarBase VL_NOT_FINAL : public VerilatedVpio {
const VerilatedVar* m_varp; protected:
const VerilatedScope* m_scopep; 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: public:
VerilatedVpioParam(const VerilatedVar* varp, const VerilatedScope* scopep) VerilatedVpioVarBase(const VerilatedVar* varp, const VerilatedScope* scopep)
: m_varp{varp} : m_varp{varp}
, m_scopep{scopep} {} , m_scopep{scopep} {}
virtual ~VerilatedVpioParam() override = default; explicit VerilatedVpioVarBase(const VerilatedVpioVarBase* varp) {
if (varp) {
static VerilatedVpioParam* castp(vpiHandle h) { m_varp = varp->m_varp;
return dynamic_cast<VerilatedVpioParam*>(reinterpret_cast<VerilatedVpio*>(h)); m_scopep = varp->m_scopep;
}
}
static VerilatedVpioVarBase* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioVarBase*>(reinterpret_cast<VerilatedVpio*>(h));
} }
virtual vluint32_t type() const override { return vpiParameter; }
const VerilatedVar* varp() const { return m_varp; } const VerilatedVar* varp() const { return m_varp; }
void* varDatap() const { return m_varp->datap(); }
const VerilatedScope* scopep() const { return m_scopep; } 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* name() const override { return m_varp->name(); }
virtual const char* fullname() const override { virtual const char* fullname() const override {
static VL_THREAD_LOCAL std::string t_out; 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<VerilatedVpioParam*>(reinterpret_cast<VerilatedVpio*>(h));
}
virtual vluint32_t type() const override { return vpiParameter; }
void* varDatap() const { return m_varp->datap(); }
};
class VerilatedVpioRange final : public VerilatedVpio { class VerilatedVpioRange final : public VerilatedVpio {
const VerilatedRange* m_range; const VerilatedRange* m_range;
@ -251,9 +273,7 @@ public:
virtual const char* fullname() const override { return m_scopep->name(); } virtual const char* fullname() const override { return m_scopep->name(); }
}; };
class VerilatedVpioVar VL_NOT_FINAL : public VerilatedVpio { class VerilatedVpioVar VL_NOT_FINAL : public VerilatedVpioVarBase {
const VerilatedVar* m_varp = nullptr;
const VerilatedScope* m_scopep = nullptr;
vluint8_t* m_prevDatap = nullptr; // Previous value of data, for cbValueChange vluint8_t* m_prevDatap = nullptr; // Previous value of data, for cbValueChange
union { union {
vluint8_t u8[4]; vluint8_t u8[4];
@ -263,23 +283,17 @@ class VerilatedVpioVar VL_NOT_FINAL : public VerilatedVpio {
protected: protected:
void* m_varDatap = nullptr; // varp()->datap() adjusted for array entries void* m_varDatap = nullptr; // varp()->datap() adjusted for array entries
vlsint32_t m_index = 0; 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: public:
VerilatedVpioVar(const VerilatedVar* varp, const VerilatedScope* scopep) VerilatedVpioVar(const VerilatedVar* varp, const VerilatedScope* scopep)
: m_varp{varp} : VerilatedVpioVarBase(varp, scopep) {
, m_scopep{scopep} {
m_mask.u32 = VL_MASK_I(varp->packed().elements()); m_mask.u32 = VL_MASK_I(varp->packed().elements());
m_entSize = varp->entSize(); m_entSize = varp->entSize();
m_varDatap = varp->datap(); m_varDatap = varp->datap();
} }
explicit VerilatedVpioVar(const VerilatedVpioVar* varp) { explicit VerilatedVpioVar(const VerilatedVpioVar* varp)
: VerilatedVpioVarBase(varp) {
if (varp) { if (varp) {
m_varp = varp->m_varp;
m_scopep = varp->m_scopep;
m_mask.u32 = varp->m_mask.u32; m_mask.u32 = varp->m_mask.u32;
m_entSize = varp->m_entSize; m_entSize = varp->m_entSize;
m_varDatap = varp->m_varDatap; m_varDatap = varp->m_varDatap;
@ -295,8 +309,6 @@ public:
static VerilatedVpioVar* castp(vpiHandle h) { static VerilatedVpioVar* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioVar*>(reinterpret_cast<VerilatedVpio*>(h)); return dynamic_cast<VerilatedVpioVar*>(reinterpret_cast<VerilatedVpio*>(h));
} }
const VerilatedVar* varp() const { return m_varp; }
const VerilatedScope* scopep() const { return m_scopep; }
vluint32_t mask() const { return m_mask.u32; } vluint32_t mask() const { return m_mask.u32; }
vluint8_t mask_byte(int idx) { return m_mask.u8[idx & 3]; } vluint8_t mask_byte(int idx) { return m_mask.u8[idx & 3]; }
vluint32_t entSize() const { return m_entSize; } vluint32_t entSize() const { return m_entSize; }
@ -304,14 +316,6 @@ public:
virtual vluint32_t type() const override { virtual vluint32_t type() const override {
return (varp()->dims() > 1) ? vpiMemory : vpiReg; // but might be wire, logic 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* prevDatap() const { return m_prevDatap; }
void* varDatap() const { return m_varDatap; } void* varDatap() const { return m_varDatap; }
void createPrevDatap() { void createPrevDatap() {
@ -1433,7 +1437,7 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) {
VL_VPI_ERROR_RESET_(); VL_VPI_ERROR_RESET_();
switch (type) { switch (type) {
case vpiLeftRange: { case vpiLeftRange: {
if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) { if (VerilatedVpioVarBase* vop = VerilatedVpioVarBase::castp(object)) {
if (VL_UNLIKELY(!vop->rangep())) return nullptr; if (VL_UNLIKELY(!vop->rangep())) return nullptr;
return (new VerilatedVpioConst(vop->rangep()->left()))->castVpiHandle(); return (new VerilatedVpioConst(vop->rangep()->left()))->castVpiHandle();
} else if (VerilatedVpioRange* vop = VerilatedVpioRange::castp(object)) { } else if (VerilatedVpioRange* vop = VerilatedVpioRange::castp(object)) {
@ -1446,7 +1450,7 @@ vpiHandle vpi_handle(PLI_INT32 type, vpiHandle object) {
return nullptr; return nullptr;
} }
case vpiRightRange: { case vpiRightRange: {
if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) { if (VerilatedVpioVarBase* vop = VerilatedVpioVarBase::castp(object)) {
if (VL_UNLIKELY(!vop->rangep())) return nullptr; if (VL_UNLIKELY(!vop->rangep())) return nullptr;
return (new VerilatedVpioConst(vop->rangep()->right()))->castVpiHandle(); return (new VerilatedVpioConst(vop->rangep()->right()))->castVpiHandle();
} else if (VerilatedVpioRange* vop = VerilatedVpioRange::castp(object)) { } 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(); return (new VerilatedVpioConst(vop->index()))->castVpiHandle();
} }
case vpiScope: { case vpiScope: {
VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); VerilatedVpioVarBase* vop = VerilatedVpioVarBase::castp(object);
if (VL_UNLIKELY(!vop)) return nullptr; if (VL_UNLIKELY(!vop)) return nullptr;
return (new VerilatedVpioScope(vop->scopep()))->castVpiHandle(); return (new VerilatedVpioScope(vop->scopep()))->castVpiHandle();
} }
@ -1568,18 +1572,18 @@ PLI_INT32 vpi_get(PLI_INT32 property, vpiHandle object) {
} }
case vpiDirection: { case vpiDirection: {
// By forthought, the directions already are vpi enumerated // By forthought, the directions already are vpi enumerated
VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); VerilatedVpioVarBase* vop = VerilatedVpioVarBase::castp(object);
if (VL_UNLIKELY(!vop)) return 0; if (VL_UNLIKELY(!vop)) return 0;
return vop->varp()->vldir(); return vop->varp()->vldir();
} }
case vpiScalar: // FALLTHRU case vpiScalar: // FALLTHRU
case vpiVector: { case vpiVector: {
VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); VerilatedVpioVarBase* vop = VerilatedVpioVarBase::castp(object);
if (VL_UNLIKELY(!vop)) return 0; if (VL_UNLIKELY(!vop)) return 0;
return (property == vpiVector) ^ (vop->varp()->dims() == 0); return (property == vpiVector) ^ (vop->varp()->dims() == 0);
} }
case vpiSize: { case vpiSize: {
VerilatedVpioVar* vop = VerilatedVpioVar::castp(object); VerilatedVpioVarBase* vop = VerilatedVpioVarBase::castp(object);
if (VL_UNLIKELY(!vop)) return 0; if (VL_UNLIKELY(!vop)) return 0;
return vop->size(); return vop->size();
} }

View File

@ -218,6 +218,8 @@ private:
if (v3Global.opt.publicFlatRW()) { if (v3Global.opt.publicFlatRW()) {
switch (nodep->varType()) { switch (nodep->varType()) {
case AstVarType::VAR: // FALLTHRU case AstVarType::VAR: // FALLTHRU
case AstVarType::GPARAM: // FALLTHRU
case AstVarType::LPARAM: // FALLTHRU
case AstVarType::PORT: // FALLTHRU case AstVarType::PORT: // FALLTHRU
case AstVarType::WIRE: nodep->sigUserRWPublic(true); break; case AstVarType::WIRE: nodep->sigUserRWPublic(true); break;
default: break; default: break;

View File

@ -163,18 +163,23 @@ int mon_check_props() {
{"fourthreetwoone", {"fourthreetwoone",
{2, vpiNoDirection, 0, vpiMemory}, {2, vpiNoDirection, 0, vpiMemory},
{2, vpiNoDirection, 0, vpiMemoryWord}}, {2, vpiNoDirection, 0, vpiMemoryWord}},
{"theint", {32, vpiNoDirection, 0, vpiReg}, {0, 0, 0, 0}},
{"clk", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}}, {"clk", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}},
{"testin", {16, vpiInput, 0, vpiPort}, {0, 0, 0, 0}}, {"testin", {16, vpiInput, 0, vpiPort}, {0, 0, 0, 0}},
{"testout", {24, vpiOutput, 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.subin", {1, vpiInput, 1, vpiPort}, {0, 0, 0, 0}},
{"sub.subout", {1, vpiOutput, 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}}, {"twobytwo", {2, vpiNoDirection, 0, vpiMemory}, {2, vpiNoDirection, 0, vpiMemoryWord}},
{NULL, {0, 0, 0, 0}, {0, 0, 0, 0}}}; {NULL, {0, 0, 0, 0}, {0, 0, 0, 0}}};
struct params* value = values; struct params* value = values;
while (value->signal) { while (value->signal) {
TestVpiHandle h = VPI_HANDLE(value->signal); TestVpiHandle h = VPI_HANDLE(value->signal);
CHECK_RESULT_NZ(h);
TEST_MSG("%s\n", value->signal); TEST_MSG("%s\n", value->signal);
CHECK_RESULT_NZ(h);
if (int status = _mon_check_props(h, value->attributes.size, value->attributes.direction, if (int status = _mon_check_props(h, value->attributes.size, value->attributes.direction,
value->attributes.scalar, value->attributes.type)) value->attributes.scalar, value->attributes.type))
return status; return status;

View File

@ -22,6 +22,11 @@ import "DPI-C" function void dpi_print(input string somestring);
`define PUBLIC_FLAT_RW `define PUBLIC_FLAT_RW
`endif `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*/ module t (/*AUTOARG*/
// Inputs // Inputs
input clk `PUBLIC_FLAT_RD, input clk `PUBLIC_FLAT_RD,
@ -43,6 +48,7 @@ extern "C" int mon_check();
reg onetwo [1:2] `PUBLIC_FLAT_RW; reg onetwo [1:2] `PUBLIC_FLAT_RW;
reg [2:1] fourthreetwoone[4:3] `PUBLIC_FLAT_RW; reg [2:1] fourthreetwoone[4:3] `PUBLIC_FLAT_RW;
reg [1:0] [1:0] twobytwo `PUBLIC_FLAT_RW; reg [1:0] [1:0] twobytwo `PUBLIC_FLAT_RW;
int theint `PUBLIC_FLAT_RW;
integer status; integer status;
@ -68,7 +74,7 @@ extern "C" int mon_check();
status = mon_check(); status = mon_check();
`endif `endif
if (status!=0) begin 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; $stop;
end end
$write("*-* All Finished *-*\n"); $write("*-* All Finished *-*\n");
@ -77,8 +83,11 @@ extern "C" int mon_check();
endmodule : t endmodule : t
module sub ( module sub #(
parameter int subparam `PUBLIC_FLAT_RD = 2
) (
input subin `PUBLIC_FLAT_RD, input subin `PUBLIC_FLAT_RD,
output subout `PUBLIC_FLAT_RD output subout `PUBLIC_FLAT_RD
); );
intf the_intf();
endmodule : sub endmodule : sub