Public interface params (#2901)
This commit is contained in:
parent
f450d51de1
commit
f446295274
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue