mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
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; }
|
||||
};
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user