mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Support vpiConstType in vpi_get() (#4761)
This commit is contained in:
parent
c5ba6e22fa
commit
fced4d6e57
@ -120,6 +120,7 @@ public:
|
||||
virtual const char* fullname() const { return "<null>"; }
|
||||
virtual const char* defname() const { return "<null>"; }
|
||||
virtual uint32_t type() const { return 0; }
|
||||
virtual uint32_t constType() const { return vpiUndefined; }
|
||||
virtual uint32_t size() const { return 0; }
|
||||
virtual const VerilatedRange* rangep() const { return nullptr; }
|
||||
virtual vpiHandle dovpi_scan() { return nullptr; }
|
||||
@ -158,6 +159,7 @@ public:
|
||||
return dynamic_cast<VerilatedVpioConst*>(reinterpret_cast<VerilatedVpio*>(h));
|
||||
}
|
||||
uint32_t type() const override { return vpiConstant; }
|
||||
uint32_t constType() const override { return vpiDecConst; }
|
||||
int32_t num() const { return m_num; }
|
||||
};
|
||||
|
||||
@ -204,6 +206,18 @@ public:
|
||||
return dynamic_cast<VerilatedVpioParam*>(reinterpret_cast<VerilatedVpio*>(h));
|
||||
}
|
||||
uint32_t type() const override { return vpiParameter; }
|
||||
uint32_t constType() const override {
|
||||
switch (m_varp->vltype()) {
|
||||
case VLVT_UINT8:
|
||||
case VLVT_UINT16:
|
||||
case VLVT_UINT32:
|
||||
case VLVT_UINT64:
|
||||
case VLVT_WDATA: return vpiDecConst;
|
||||
case VLVT_STRING: return vpiStringConst;
|
||||
case VLVT_REAL: return vpiRealConst;
|
||||
default: return vpiUndefined;
|
||||
}
|
||||
}
|
||||
void* varDatap() const { return m_varp->datap(); }
|
||||
};
|
||||
|
||||
@ -1960,6 +1974,11 @@ PLI_INT32 vpi_get(PLI_INT32 property, vpiHandle object) {
|
||||
if (VL_UNLIKELY(!vop)) return 0;
|
||||
return vop->type();
|
||||
}
|
||||
case vpiConstType: {
|
||||
const VerilatedVpio* const vop = VerilatedVpio::castp(object);
|
||||
if (VL_UNLIKELY(!vop)) return 0;
|
||||
return vop->constType();
|
||||
}
|
||||
case vpiDirection: {
|
||||
// By forethought, the directions already are vpi enumerated
|
||||
const VerilatedVpioVarBase* const vop = VerilatedVpioVarBase::castp(object);
|
||||
|
200
test_regress/t/t_vpi_const_type.cpp
Normal file
200
test_regress/t/t_vpi_const_type.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2010-2011 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#ifdef IS_VPI
|
||||
|
||||
#include "sv_vpi_user.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#else
|
||||
|
||||
#include "verilated.h"
|
||||
#include "verilated_vcd_c.h"
|
||||
#include "verilated_vpi.h"
|
||||
|
||||
#include "Vt_vpi_const_type.h"
|
||||
#include "Vt_vpi_const_type__Dpi.h"
|
||||
#include "svdpi.h"
|
||||
|
||||
#endif
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
// These require the above. Comment prevents clang-format moving them
|
||||
#include "TestSimulator.h"
|
||||
#include "TestVpi.h"
|
||||
|
||||
// __FILE__ is too long
|
||||
#define FILENM "t_vpi_const_type.cpp"
|
||||
|
||||
#define DEBUG \
|
||||
if (0) printf
|
||||
|
||||
#define CHECK_RESULT_NZ(got) \
|
||||
if (!(got)) { \
|
||||
printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM, __LINE__); \
|
||||
return __LINE__; \
|
||||
}
|
||||
|
||||
#define CHECK_RESULT_Z(got) \
|
||||
if (got) { \
|
||||
printf("%%Error: %s:%d: GOT = !NULL EXP = NULL\n", FILENM, __LINE__); \
|
||||
return __LINE__; \
|
||||
}
|
||||
|
||||
#define CHECK_RESULT(got, exp) \
|
||||
if ((got) != (exp)) { \
|
||||
std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << ": GOT = " << (got) \
|
||||
<< " EXP = " << (exp) << std::endl; \
|
||||
return __LINE__; \
|
||||
}
|
||||
|
||||
#define CHECK_RESULT_CSTR(got, exp) \
|
||||
if (std::strcmp((got), (exp))) { \
|
||||
printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", FILENM, __LINE__, \
|
||||
(got) ? (got) : "<null>", (exp) ? (exp) : "<null>"); \
|
||||
return __LINE__; \
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
int mon_check() {
|
||||
#ifdef TEST_VERBOSE
|
||||
printf("-mon_check()\n");
|
||||
#endif
|
||||
|
||||
TestVpiHandle intHandle = vpi_handle_by_name((PLI_BYTE8*)"t.intParam", NULL);
|
||||
CHECK_RESULT_NZ(intHandle)
|
||||
PLI_INT32 intConstType = vpi_get(vpiConstType, intHandle);
|
||||
CHECK_RESULT(intConstType, vpiDecConst)
|
||||
|
||||
TestVpiHandle realHandle = vpi_handle_by_name((PLI_BYTE8*)"t.realParam", NULL);
|
||||
CHECK_RESULT_NZ(realHandle)
|
||||
PLI_INT32 realConstType = vpi_get(vpiConstType, realHandle);
|
||||
CHECK_RESULT(realConstType, vpiRealConst)
|
||||
|
||||
TestVpiHandle strHandle = vpi_handle_by_name((PLI_BYTE8*)"t.strParam", NULL);
|
||||
CHECK_RESULT_NZ(strHandle)
|
||||
PLI_INT32 strConstType = vpi_get(vpiConstType, strHandle);
|
||||
CHECK_RESULT(strConstType, vpiStringConst)
|
||||
|
||||
TestVpiHandle sigHandle = vpi_handle_by_name((PLI_BYTE8*)"t.signal", NULL);
|
||||
CHECK_RESULT_NZ(sigHandle)
|
||||
PLI_INT32 sigConstType = vpi_get(vpiConstType, sigHandle);
|
||||
// t.signal is not constant
|
||||
CHECK_RESULT(sigConstType, vpiUndefined)
|
||||
TestVpiHandle leftHandle = vpi_handle(vpiLeftRange, sigHandle);
|
||||
CHECK_RESULT_NZ(leftHandle)
|
||||
PLI_INT32 leftConstType = vpi_get(vpiConstType, leftHandle);
|
||||
CHECK_RESULT(leftConstType, vpiDecConst)
|
||||
|
||||
TestVpiHandle timeHandle = vpi_handle_by_name((PLI_BYTE8*)"t.timeParam", NULL);
|
||||
CHECK_RESULT_NZ(timeHandle)
|
||||
PLI_INT32 timeConstType = vpi_get(vpiConstType, timeHandle);
|
||||
CHECK_RESULT(timeConstType, vpiDecConst)
|
||||
|
||||
return 0; // Ok
|
||||
}
|
||||
}
|
||||
//======================================================================
|
||||
|
||||
#ifdef IS_VPI
|
||||
|
||||
static int mon_check_vpi() {
|
||||
TestVpiHandle href = vpi_handle(vpiSysTfCall, 0);
|
||||
s_vpi_value vpi_value;
|
||||
|
||||
vpi_value.format = vpiIntVal;
|
||||
vpi_value.value.integer = mon_check();
|
||||
vpi_put_value(href, &vpi_value, NULL, vpiNoDelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s_vpi_systf_data vpi_systf_data[] = {{vpiSysFunc, vpiIntFunc, (PLI_BYTE8*)"$mon_check",
|
||||
(PLI_INT32(*)(PLI_BYTE8*))mon_check_vpi, 0, 0, 0},
|
||||
0};
|
||||
|
||||
// cver entry
|
||||
void vpi_compat_bootstrap(void) {
|
||||
p_vpi_systf_data systf_data_p;
|
||||
systf_data_p = &(vpi_systf_data[0]);
|
||||
while (systf_data_p->type != 0) vpi_register_systf(systf_data_p++);
|
||||
}
|
||||
|
||||
// icarus entry
|
||||
void (*vlog_startup_routines[])() = {vpi_compat_bootstrap, 0};
|
||||
|
||||
#else
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
|
||||
|
||||
uint64_t sim_time = 1100;
|
||||
contextp->debug(0);
|
||||
contextp->commandArgs(argc, argv);
|
||||
// We're going to be checking for these errors so don't crash out
|
||||
contextp->fatalOnVpiError(0);
|
||||
|
||||
{
|
||||
// Construct and destroy
|
||||
const std::unique_ptr<VM_PREFIX> topp{
|
||||
new VM_PREFIX{contextp.get(),
|
||||
// Note null name - we're flattening it out
|
||||
""}};
|
||||
}
|
||||
|
||||
// Test second construction
|
||||
const std::unique_ptr<VM_PREFIX> topp{new VM_PREFIX{contextp.get(),
|
||||
// Note null name - we're flattening it out
|
||||
""}};
|
||||
|
||||
#ifdef VERILATOR
|
||||
#ifdef TEST_VERBOSE
|
||||
contextp->scopesDump();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if VM_TRACE
|
||||
contextp->traceEverOn(true);
|
||||
VL_PRINTF("Enabling waves...\n");
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
topp->trace(tfp, 99);
|
||||
tfp->open(STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
|
||||
#endif
|
||||
|
||||
topp->eval();
|
||||
contextp->timeInc(10);
|
||||
|
||||
while (contextp->time() < sim_time && !contextp->gotFinish()) {
|
||||
contextp->timeInc(1);
|
||||
topp->eval();
|
||||
VerilatedVpi::callValueCbs();
|
||||
// mon_do();
|
||||
#if VM_TRACE
|
||||
if (tfp) tfp->dump(contextp->time());
|
||||
#endif
|
||||
}
|
||||
if (!contextp->gotFinish()) {
|
||||
vl_fatal(FILENM, __LINE__, "main", "%Error: Timeout; never got a $finish");
|
||||
}
|
||||
topp->final();
|
||||
|
||||
#if VM_TRACE
|
||||
if (tfp) tfp->close();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
29
test_regress/t/t_vpi_const_type.pl
Executable file
29
test_regress/t/t_vpi_const_type.pl
Executable file
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2010 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
skip("Known compiler limitation")
|
||||
if $Self->cxx_version =~ /\(GCC\) 4.4/;
|
||||
|
||||
compile(
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
make_pli => 1,
|
||||
verilator_flags2 => ["--exe --vpi --no-l2name $Self->{t_dir}/t_vpi_const_type.cpp"],
|
||||
);
|
||||
|
||||
execute(
|
||||
use_libvpi => 1,
|
||||
check_finished => 1
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
33
test_regress/t/t_vpi_const_type.v
Normal file
33
test_regress/t/t_vpi_const_type.v
Normal file
@ -0,0 +1,33 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// Copyright 2010 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import "DPI-C" context function int mon_check();
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
); /*verilator public_module*/
|
||||
|
||||
parameter int intParam /*verilator public_flat_rd*/ = 5;
|
||||
parameter real realParam /*verilator public_flat_rd*/ = 2.3;
|
||||
parameter time timeParam /*verilator public_flat_rd*/ = 0;
|
||||
parameter string strParam /*verilator public_flat_rd*/ = "abc";
|
||||
|
||||
logic [31:0] signal /*verilator public_flat_rw*/;
|
||||
|
||||
int status;
|
||||
|
||||
initial begin
|
||||
status = mon_check();
|
||||
if (status!=0) begin
|
||||
$write("%%Error: t_vpi_const_type.cpp:%0d: C Test failed\n", status);
|
||||
$stop;
|
||||
end
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule : t
|
Loading…
Reference in New Issue
Block a user