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; }
};
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<VerilatedVpioParam*>(reinterpret_cast<VerilatedVpio*>(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<VerilatedVpioVarBase*>(reinterpret_cast<VerilatedVpio*>(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<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 {
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<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; }
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();
}

View File

@ -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;

View File

@ -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;

View File

@ -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