mirror of
https://github.com/verilator/verilator.git
synced 2025-01-01 04:07:34 +00:00
Support VPI product info, warning calls, etc, bug588.
This commit is contained in:
parent
de4016dcff
commit
e7ba6ef492
2
Changes
2
Changes
@ -12,6 +12,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||||||
|
|
||||||
*** Support bind, to module names only, bug602. [Ed Lander]
|
*** Support bind, to module names only, bug602. [Ed Lander]
|
||||||
|
|
||||||
|
*** Support VPI product info, warning calls, etc, bug588. [Rick Porter]
|
||||||
|
|
||||||
*** Define SYSTEMVERILOG, SV_COV_START and other IEEE mandated predefines.
|
*** Define SYSTEMVERILOG, SV_COV_START and other IEEE mandated predefines.
|
||||||
|
|
||||||
**** Fix pin width mismatch error, bug595. [Alex Solomatnikov]
|
**** Fix pin width mismatch error, bug595. [Alex Solomatnikov]
|
||||||
|
@ -455,7 +455,7 @@ clean mostlyclean distclean maintainer-clean::
|
|||||||
|
|
||||||
distclean maintainer-clean::
|
distclean maintainer-clean::
|
||||||
rm -f Makefile config.status config.cache config.log verilator_bin* TAGS
|
rm -f Makefile config.status config.cache config.log verilator_bin* TAGS
|
||||||
rm -f include/verilated.mk
|
rm -f include/verilated.mk include/verilated_config.h
|
||||||
|
|
||||||
TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/*.in \
|
TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/*.in \
|
||||||
${srcdir}/*.in ${srcdir}/*.pod
|
${srcdir}/*.in ${srcdir}/*.pod
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#AC_INIT([Verilator],[#.### devel])
|
#AC_INIT([Verilator],[#.### devel])
|
||||||
AC_INIT([Verilator],[3.845 devel])
|
AC_INIT([Verilator],[3.845 devel])
|
||||||
AC_CONFIG_HEADER(src/config_build.h)
|
AC_CONFIG_HEADER(src/config_build.h)
|
||||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk)
|
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
|
||||||
|
|
||||||
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
||||||
|
|
||||||
|
1
include/.gitignore
vendored
1
include/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
verilated.mk
|
verilated.mk
|
||||||
|
verilated_config.h
|
||||||
|
@ -40,6 +40,7 @@ Verilated::Serialized Verilated::s_s;
|
|||||||
VL_THREAD const VerilatedScope* Verilated::t_dpiScopep = NULL;
|
VL_THREAD const VerilatedScope* Verilated::t_dpiScopep = NULL;
|
||||||
VL_THREAD const char* Verilated::t_dpiFilename = "";
|
VL_THREAD const char* Verilated::t_dpiFilename = "";
|
||||||
VL_THREAD int Verilated::t_dpiLineno = 0;
|
VL_THREAD int Verilated::t_dpiLineno = 0;
|
||||||
|
struct Verilated::CommandArgValues Verilated::s_args = {0, NULL};
|
||||||
|
|
||||||
VerilatedImp VerilatedImp::s_s;
|
VerilatedImp VerilatedImp::s_s;
|
||||||
|
|
||||||
@ -86,6 +87,7 @@ Verilated::Serialized::Serialized() {
|
|||||||
s_calcUnusedSigs = false;
|
s_calcUnusedSigs = false;
|
||||||
s_gotFinish = false;
|
s_gotFinish = false;
|
||||||
s_assertOn = true;
|
s_assertOn = true;
|
||||||
|
s_fatalOnVpiError = true; // retains old default behaviour
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
@ -1064,6 +1066,8 @@ void Verilated::flushCb(VerilatedVoidCb cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Verilated::commandArgs(int argc, const char** argv) {
|
void Verilated::commandArgs(int argc, const char** argv) {
|
||||||
|
s_args.argc = argc;
|
||||||
|
s_args.argv = argv;
|
||||||
VerilatedImp::commandArgs(argc,argv);
|
VerilatedImp::commandArgs(argc,argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#ifndef _VERILATED_H_
|
#ifndef _VERILATED_H_
|
||||||
#define _VERILATED_H_ 1 ///< Header Guard
|
#define _VERILATED_H_ 1 ///< Header Guard
|
||||||
|
|
||||||
|
#include "verilated_config.h"
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -229,6 +230,7 @@ private:
|
|||||||
bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated
|
bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated
|
||||||
bool s_gotFinish; ///< A $finish statement executed
|
bool s_gotFinish; ///< A $finish statement executed
|
||||||
bool s_assertOn; ///< Assertions are enabled
|
bool s_assertOn; ///< Assertions are enabled
|
||||||
|
bool s_fatalOnVpiError; ///< Stop on vpi error/unsupported
|
||||||
Serialized();
|
Serialized();
|
||||||
} s_s;
|
} s_s;
|
||||||
|
|
||||||
@ -236,6 +238,13 @@ private:
|
|||||||
static VL_THREAD const char* t_dpiFilename; ///< DPI context filename
|
static VL_THREAD const char* t_dpiFilename; ///< DPI context filename
|
||||||
static VL_THREAD int t_dpiLineno; ///< DPI context line number
|
static VL_THREAD int t_dpiLineno; ///< DPI context line number
|
||||||
|
|
||||||
|
// no need to be save-restored (serialized) the
|
||||||
|
// assumption is that the restore is allowed to pass different arguments
|
||||||
|
static struct CommandArgValues {
|
||||||
|
int argc;
|
||||||
|
const char** argv;
|
||||||
|
} s_args;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// METHODS - User called
|
// METHODS - User called
|
||||||
@ -268,6 +277,9 @@ public:
|
|||||||
/// Enable/disable assertions
|
/// Enable/disable assertions
|
||||||
static void assertOn(bool flag) { s_s.s_assertOn=flag; }
|
static void assertOn(bool flag) { s_s.s_assertOn=flag; }
|
||||||
static bool assertOn() { return s_s.s_assertOn; }
|
static bool assertOn() { return s_s.s_assertOn; }
|
||||||
|
/// Enable/disable vpi fatal
|
||||||
|
static void fatalOnVpiError(bool flag) { s_s.s_fatalOnVpiError=flag; }
|
||||||
|
static bool fatalOnVpiError() { return s_s.s_fatalOnVpiError; }
|
||||||
/// Flush callback for VCD waves
|
/// Flush callback for VCD waves
|
||||||
static void flushCb(VerilatedVoidCb cb);
|
static void flushCb(VerilatedVoidCb cb);
|
||||||
static void flushCall() { if (s_flushCb) (*s_flushCb)(); }
|
static void flushCall() { if (s_flushCb) (*s_flushCb)(); }
|
||||||
@ -275,8 +287,13 @@ public:
|
|||||||
/// Record command line arguments, for retrieval by $test$plusargs/$value$plusargs
|
/// Record command line arguments, for retrieval by $test$plusargs/$value$plusargs
|
||||||
static void commandArgs(int argc, const char** argv);
|
static void commandArgs(int argc, const char** argv);
|
||||||
static void commandArgs(int argc, char** argv) { commandArgs(argc,(const char**)argv); }
|
static void commandArgs(int argc, char** argv) { commandArgs(argc,(const char**)argv); }
|
||||||
|
static CommandArgValues* getCommandArgs() {return &s_args;}
|
||||||
static const char* commandArgsPlusMatch(const char* prefixp);
|
static const char* commandArgsPlusMatch(const char* prefixp);
|
||||||
|
|
||||||
|
/// Produce name & version for (at least) VPI
|
||||||
|
static const char* productName() { return VERILATOR_PRODUCT; }
|
||||||
|
static const char* productVersion() { return VERILATOR_VERSION; }
|
||||||
|
|
||||||
/// For debugging, print text list of all scope names with
|
/// For debugging, print text list of all scope names with
|
||||||
/// dpiImport/Export context. This function may change in future
|
/// dpiImport/Export context. This function may change in future
|
||||||
/// releases - contact the authors before production use.
|
/// releases - contact the authors before production use.
|
||||||
|
28
include/verilated_config.h.in
Normal file
28
include/verilated_config.h.in
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||||
|
//*************************************************************************
|
||||||
|
//
|
||||||
|
// Copyright 2003-2012 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.
|
||||||
|
//
|
||||||
|
// Verilator is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
///
|
||||||
|
/// \file
|
||||||
|
/// \brief Verilator: Auto version information include for all Verilated C files
|
||||||
|
///
|
||||||
|
/// Code available from: http://www.veripool.org/verilator
|
||||||
|
///
|
||||||
|
//*************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
///**** Product and Version name
|
||||||
|
|
||||||
|
// Autoconf substitutes this with the strings from AC_INIT.
|
||||||
|
#define VERILATOR_PRODUCT "@PACKAGE_NAME@"
|
||||||
|
#define VERILATOR_VERSION "@PACKAGE_VERSION@"
|
@ -31,3 +31,334 @@ VerilatedVpi VerilatedVpi::s_s; // Singleton
|
|||||||
vluint8_t* VerilatedVpio::s_freeHead = NULL;
|
vluint8_t* VerilatedVpio::s_freeHead = NULL;
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
|
const char* VerilatedVpiError::strFromVpiVal(PLI_INT32 vpiVal) {
|
||||||
|
static const char *names[] = {
|
||||||
|
"*undefined*",
|
||||||
|
"vpiBinStrVal",
|
||||||
|
"vpiOctStrVal",
|
||||||
|
"vpiDecStrVal",
|
||||||
|
"vpiHexStrVal",
|
||||||
|
"vpiScalarVal",
|
||||||
|
"vpiIntVal",
|
||||||
|
"vpiRealVal",
|
||||||
|
"vpiStringVal",
|
||||||
|
"vpiVectorVal",
|
||||||
|
"vpiStrengthVal",
|
||||||
|
"vpiTimeVal",
|
||||||
|
"vpiObjTypeVal",
|
||||||
|
"vpiSuppressVal",
|
||||||
|
"vpiShortIntVal",
|
||||||
|
"vpiLongIntVal",
|
||||||
|
"vpiShortRealVal",
|
||||||
|
"vpiRawTwoStateVal",
|
||||||
|
"vpiRawFourStateVal",
|
||||||
|
};
|
||||||
|
if (vpiVal < 0) return names[0];
|
||||||
|
return names[(vpiVal<=vpiRawFourStateVal)?vpiVal:0];
|
||||||
|
}
|
||||||
|
const char* VerilatedVpiError::strFromVpiObjType(PLI_INT32 vpiVal) {
|
||||||
|
static const char *names[] = {
|
||||||
|
"*undefined*",
|
||||||
|
"vpiAlways",
|
||||||
|
"vpiAssignStmt",
|
||||||
|
"vpiAssignment",
|
||||||
|
"vpiBegin",
|
||||||
|
"vpiCase",
|
||||||
|
"vpiCaseItem",
|
||||||
|
"vpiConstant",
|
||||||
|
"vpiContAssign",
|
||||||
|
"vpiDeassign",
|
||||||
|
"vpiDefParam",
|
||||||
|
"vpiDelayControl",
|
||||||
|
"vpiDisable",
|
||||||
|
"vpiEventControl",
|
||||||
|
"vpiEventStmt",
|
||||||
|
"vpiFor",
|
||||||
|
"vpiForce",
|
||||||
|
"vpiForever",
|
||||||
|
"vpiFork",
|
||||||
|
"vpiFuncCall",
|
||||||
|
"vpiFunction",
|
||||||
|
"vpiGate",
|
||||||
|
"vpiIf",
|
||||||
|
"vpiIfElse",
|
||||||
|
"vpiInitial",
|
||||||
|
"vpiIntegerVar",
|
||||||
|
"vpiInterModPath",
|
||||||
|
"vpiIterator",
|
||||||
|
"vpiIODecl",
|
||||||
|
"vpiMemory",
|
||||||
|
"vpiMemoryWord",
|
||||||
|
"vpiModPath",
|
||||||
|
"vpiModule",
|
||||||
|
"vpiNamedBegin",
|
||||||
|
"vpiNamedEvent",
|
||||||
|
"vpiNamedFork",
|
||||||
|
"vpiNet",
|
||||||
|
"vpiNetBit",
|
||||||
|
"vpiNullStmt",
|
||||||
|
"vpiOperation",
|
||||||
|
"vpiParamAssign",
|
||||||
|
"vpiParameter",
|
||||||
|
"vpiPartSelect",
|
||||||
|
"vpiPathTerm",
|
||||||
|
"vpiPort",
|
||||||
|
"vpiPortBit",
|
||||||
|
"vpiPrimTerm",
|
||||||
|
"vpiRealVar",
|
||||||
|
"vpiReg",
|
||||||
|
"vpiRegBit",
|
||||||
|
"vpiRelease",
|
||||||
|
"vpiRepeat",
|
||||||
|
"vpiRepeatControl",
|
||||||
|
"vpiSchedEvent",
|
||||||
|
"vpiSpecParam",
|
||||||
|
"vpiSwitch",
|
||||||
|
"vpiSysFuncCall",
|
||||||
|
"vpiSysTaskCall",
|
||||||
|
"vpiTableEntry",
|
||||||
|
"vpiTask",
|
||||||
|
"vpiTaskCall",
|
||||||
|
"vpiTchk",
|
||||||
|
"vpiTchkTerm",
|
||||||
|
"vpiTimeVar",
|
||||||
|
"vpiTimeQueue",
|
||||||
|
"vpiUdp",
|
||||||
|
"vpiUdpDefn",
|
||||||
|
"vpiUserSystf",
|
||||||
|
"vpiVarSelect",
|
||||||
|
"vpiWait",
|
||||||
|
"vpiWhile",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"vpiAttribute",
|
||||||
|
"vpiBitSelect",
|
||||||
|
"vpiCallback",
|
||||||
|
"vpiDelayTerm",
|
||||||
|
"vpiDelayDevice",
|
||||||
|
"vpiFrame",
|
||||||
|
"vpiGateArray",
|
||||||
|
"vpiModuleArray",
|
||||||
|
"vpiPrimitiveArray",
|
||||||
|
"vpiNetArray",
|
||||||
|
"vpiRange",
|
||||||
|
"vpiRegArray",
|
||||||
|
"vpiSwitchArray",
|
||||||
|
"vpiUdpArray",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"vpiContAssignBit",
|
||||||
|
"vpiNamedEventArray",
|
||||||
|
"vpiIndexedPartSelect",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"vpiGenScopeArray",
|
||||||
|
"vpiGenScope",
|
||||||
|
"vpiGenVar"
|
||||||
|
};
|
||||||
|
if (vpiVal < 0) return names[0];
|
||||||
|
return names[(vpiVal<=vpiGenVar)?vpiVal:0];
|
||||||
|
}
|
||||||
|
const char* VerilatedVpiError::strFromVpiMethod(PLI_INT32 vpiVal) {
|
||||||
|
static const char *names[] = {
|
||||||
|
"vpiCondition",
|
||||||
|
"vpiDelay",
|
||||||
|
"vpiElseStmt",
|
||||||
|
"vpiForIncStmt",
|
||||||
|
"vpiForInitStmt",
|
||||||
|
"vpiHighConn",
|
||||||
|
"vpiLhs",
|
||||||
|
"vpiIndex",
|
||||||
|
"vpiLeftRange",
|
||||||
|
"vpiLowConn",
|
||||||
|
"vpiParent",
|
||||||
|
"vpiRhs",
|
||||||
|
"vpiRightRange",
|
||||||
|
"vpiScope",
|
||||||
|
"vpiSysTfCall",
|
||||||
|
"vpiTchkDataTerm",
|
||||||
|
"vpiTchkNotifier",
|
||||||
|
"vpiTchkRefTerm",
|
||||||
|
"vpiArgument",
|
||||||
|
"vpiBit",
|
||||||
|
"vpiDriver",
|
||||||
|
"vpiInternalScope",
|
||||||
|
"vpiLoad",
|
||||||
|
"vpiModDataPathIn",
|
||||||
|
"vpiModPathIn",
|
||||||
|
"vpiModPathOut",
|
||||||
|
"vpiOperand",
|
||||||
|
"vpiPortInst",
|
||||||
|
"vpiProcess",
|
||||||
|
"vpiVariables",
|
||||||
|
"vpiUse",
|
||||||
|
"vpiExpr",
|
||||||
|
"vpiPrimitive",
|
||||||
|
"vpiStmt"
|
||||||
|
};
|
||||||
|
if (vpiVal>vpiStmt || vpiVal<vpiCondition) {
|
||||||
|
return "*undefined*";
|
||||||
|
}
|
||||||
|
return names[vpiVal-vpiCondition];
|
||||||
|
}
|
||||||
|
const char* VerilatedVpiError::strFromVpiCallbackReason(PLI_INT32 vpiVal) {
|
||||||
|
static const char *names[] = {
|
||||||
|
"*undefined*",
|
||||||
|
"cbValueChange",
|
||||||
|
"cbStmt",
|
||||||
|
"cbForce",
|
||||||
|
"cbRelease",
|
||||||
|
"cbAtStartOfSimTime",
|
||||||
|
"cbReadWriteSynch",
|
||||||
|
"cbReadOnlySynch",
|
||||||
|
"cbNextSimTime",
|
||||||
|
"cbAfterDelay",
|
||||||
|
"cbEndOfCompile",
|
||||||
|
"cbStartOfSimulation",
|
||||||
|
"cbEndOfSimulation",
|
||||||
|
"cbError",
|
||||||
|
"cbTchkViolation",
|
||||||
|
"cbStartOfSave",
|
||||||
|
"cbEndOfSave",
|
||||||
|
"cbStartOfRestart",
|
||||||
|
"cbEndOfRestart",
|
||||||
|
"cbStartOfReset",
|
||||||
|
"cbEndOfReset",
|
||||||
|
"cbEnterInteractive",
|
||||||
|
"cbExitInteractive",
|
||||||
|
"cbInteractiveScopeChange",
|
||||||
|
"cbUnresolvedSystf",
|
||||||
|
"cbAssign",
|
||||||
|
"cbDeassign",
|
||||||
|
"cbDisable",
|
||||||
|
"cbPLIError",
|
||||||
|
"cbSignal",
|
||||||
|
"cbNBASynch",
|
||||||
|
"cbAtEndOfSimTime"
|
||||||
|
};
|
||||||
|
if (vpiVal < 0) return names[0];
|
||||||
|
return names[(vpiVal<=cbAtEndOfSimTime)?vpiVal:0];
|
||||||
|
}
|
||||||
|
const char* VerilatedVpiError::strFromVpiProp(PLI_INT32 vpiVal) {
|
||||||
|
static const char *names[] = {
|
||||||
|
"*undefined or other*",
|
||||||
|
"vpiType",
|
||||||
|
"vpiName",
|
||||||
|
"vpiFullName",
|
||||||
|
"vpiSize",
|
||||||
|
"vpiFile",
|
||||||
|
"vpiLineNo",
|
||||||
|
"vpiTopModule",
|
||||||
|
"vpiCellInstance",
|
||||||
|
"vpiDefName",
|
||||||
|
"vpiProtected",
|
||||||
|
"vpiTimeUnit",
|
||||||
|
"vpiTimePrecision",
|
||||||
|
"vpiDefNetType",
|
||||||
|
"vpiUnconnDrive",
|
||||||
|
"vpiDefFile",
|
||||||
|
"vpiDefLineNo",
|
||||||
|
"vpiScalar",
|
||||||
|
"vpiVector",
|
||||||
|
"vpiExplicitName",
|
||||||
|
"vpiDirection",
|
||||||
|
"vpiConnByName",
|
||||||
|
"vpiNetType",
|
||||||
|
"vpiExplicitScalared",
|
||||||
|
"vpiExplicitVectored",
|
||||||
|
"vpiExpanded",
|
||||||
|
"vpiImplicitDecl",
|
||||||
|
"vpiChargeStrength",
|
||||||
|
"vpiArray",
|
||||||
|
"vpiPortIndex",
|
||||||
|
"vpiTermIndex",
|
||||||
|
"vpiStrength0",
|
||||||
|
"vpiStrength1",
|
||||||
|
"vpiPrimType",
|
||||||
|
"vpiPolarity",
|
||||||
|
"vpiDataPolarity",
|
||||||
|
"vpiEdge",
|
||||||
|
"vpiPathType",
|
||||||
|
"vpiTchkType",
|
||||||
|
"vpiOpType",
|
||||||
|
"vpiConstType",
|
||||||
|
"vpiBlocking",
|
||||||
|
"vpiCaseType",
|
||||||
|
"vpiFuncType",
|
||||||
|
"vpiNetDeclAssign",
|
||||||
|
"vpiUserDefn",
|
||||||
|
"vpiScheduled",
|
||||||
|
"*undefined*",
|
||||||
|
"*undefined*",
|
||||||
|
"vpiActive",
|
||||||
|
"vpiAutomatic",
|
||||||
|
"vpiCell",
|
||||||
|
"vpiConfig",
|
||||||
|
"vpiConstantSelect",
|
||||||
|
"vpiDecompile",
|
||||||
|
"vpiDefAttribute",
|
||||||
|
"vpiDelayType",
|
||||||
|
"vpiIteratorType",
|
||||||
|
"vpiLibrary",
|
||||||
|
"*undefined*",
|
||||||
|
"vpiOffset",
|
||||||
|
"vpiResolvedNetType",
|
||||||
|
"vpiSaveRestartID",
|
||||||
|
"vpiSaveRestartLocation",
|
||||||
|
"vpiValid",
|
||||||
|
"vpiSigned",
|
||||||
|
"vpiStop",
|
||||||
|
"vpiFinish",
|
||||||
|
"vpiReset",
|
||||||
|
"vpiSetInteractiveScope",
|
||||||
|
"vpiLocalParam",
|
||||||
|
"vpiModPathHasIfNone",
|
||||||
|
"vpiIndexedPartSelectType",
|
||||||
|
"vpiIsMemory",
|
||||||
|
"vpiIsProtected"
|
||||||
|
};
|
||||||
|
if (vpiVal == vpiUndefined) {
|
||||||
|
return "vpiUndefined";
|
||||||
|
}
|
||||||
|
return names[(vpiVal<=vpiIsProtected)?vpiVal:0];
|
||||||
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
208
test_regress/t/t_vpi_unimpl.cpp
Normal file
208
test_regress/t/t_vpi_unimpl.cpp
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
// -*- 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.
|
||||||
|
//
|
||||||
|
// Verilator is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
//*************************************************************************
|
||||||
|
|
||||||
|
#include "Vt_vpi_unimpl.h"
|
||||||
|
#include "verilated.h"
|
||||||
|
#include "svdpi.h"
|
||||||
|
|
||||||
|
#include "Vt_vpi_unimpl__Dpi.h"
|
||||||
|
|
||||||
|
#include "verilated_vpi.h"
|
||||||
|
#include "verilated_vpi.cpp"
|
||||||
|
#include "verilated_vcd_c.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// __FILE__ is too long
|
||||||
|
#define FILENM "t_vpi_unimpl.cpp"
|
||||||
|
|
||||||
|
#define DEBUG if (0) printf
|
||||||
|
|
||||||
|
unsigned int main_time = false;
|
||||||
|
unsigned int callback_count = false;
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
|
||||||
|
class VlVpiHandle {
|
||||||
|
/// For testing, etc, wrap vpiHandle in an auto-releasing class
|
||||||
|
vpiHandle m_handle;
|
||||||
|
public:
|
||||||
|
VlVpiHandle() : m_handle(NULL) { }
|
||||||
|
VlVpiHandle(vpiHandle h) : m_handle(h) { }
|
||||||
|
~VlVpiHandle() { if (m_handle) { vpi_release_handle(m_handle); m_handle=NULL; } }
|
||||||
|
operator vpiHandle () const { return m_handle; }
|
||||||
|
inline VlVpiHandle& operator= (vpiHandle h) { m_handle = h; return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
#define CHECK_RESULT_VH(got, exp) \
|
||||||
|
if ((got) != (exp)) { \
|
||||||
|
printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \
|
||||||
|
FILENM,__LINE__, (got), (exp)); \
|
||||||
|
return __LINE__; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK_RESULT_NZ(got) \
|
||||||
|
if (!(got)) { \
|
||||||
|
printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \
|
||||||
|
return __LINE__; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use cout to avoid issues with %d/%lx etc
|
||||||
|
#define CHECK_RESULT(got, exp) \
|
||||||
|
if ((got != exp)) { \
|
||||||
|
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__ \
|
||||||
|
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
|
||||||
|
return __LINE__; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK_RESULT_HEX(got, exp) \
|
||||||
|
if ((got != exp)) { \
|
||||||
|
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__<<hex \
|
||||||
|
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
|
||||||
|
return __LINE__; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK_RESULT_CSTR(got, exp) \
|
||||||
|
if (strcmp((got),(exp))) { \
|
||||||
|
printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", \
|
||||||
|
FILENM,__LINE__, (got)?(got):"<null>", (exp)?(exp):"<null>"); \
|
||||||
|
return __LINE__; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK_RESULT_CSTR_STRIP(got, exp) \
|
||||||
|
CHECK_RESULT_CSTR(got+strspn(got, " "), exp)
|
||||||
|
|
||||||
|
int _mon_check_unimpl(p_cb_data cb_data) {
|
||||||
|
static VlVpiHandle cb, clk_h;
|
||||||
|
if (cb_data) {
|
||||||
|
// this is the callback
|
||||||
|
s_vpi_error_info info;
|
||||||
|
vpi_chk_error(&info);
|
||||||
|
callback_count++;
|
||||||
|
printf("%%Info: got pli message %s\n", info.message);
|
||||||
|
} else {
|
||||||
|
// setup and install
|
||||||
|
static t_cb_data cb_data;
|
||||||
|
clk_h = vpi_handle_by_name((PLI_BYTE8*)"t.clk", NULL);
|
||||||
|
|
||||||
|
cb_data.reason = cbPLIError;
|
||||||
|
cb_data.cb_rtn = _mon_check_unimpl; // this function
|
||||||
|
|
||||||
|
cb = vpi_register_cb(&cb_data);
|
||||||
|
CHECK_RESULT_NZ(cb);
|
||||||
|
|
||||||
|
// now exercise unimplemented fns
|
||||||
|
vpi_get_cb_info(cb, NULL);
|
||||||
|
CHECK_RESULT(callback_count, 1);
|
||||||
|
vpi_register_systf(NULL);
|
||||||
|
CHECK_RESULT(callback_count, 2);
|
||||||
|
vpi_get_systf_info(NULL, NULL);
|
||||||
|
CHECK_RESULT(callback_count, 3);
|
||||||
|
vpi_handle_multi(0, NULL, NULL);
|
||||||
|
CHECK_RESULT(callback_count, 4);
|
||||||
|
vpi_get64(0, NULL);
|
||||||
|
CHECK_RESULT(callback_count, 5);
|
||||||
|
vpi_get_delays(NULL, NULL);
|
||||||
|
CHECK_RESULT(callback_count, 6);
|
||||||
|
vpi_put_delays(NULL, NULL);
|
||||||
|
CHECK_RESULT(callback_count, 7);
|
||||||
|
vpi_get_value_array(NULL, NULL, NULL, 0);
|
||||||
|
CHECK_RESULT(callback_count, 8);
|
||||||
|
vpi_put_value_array(NULL, NULL, NULL, 0);
|
||||||
|
CHECK_RESULT(callback_count, 9);
|
||||||
|
vpi_get_time(NULL, NULL);
|
||||||
|
CHECK_RESULT(callback_count, 10);
|
||||||
|
vpi_mcd_name(0);
|
||||||
|
CHECK_RESULT(callback_count, 11);
|
||||||
|
vpi_compare_objects(NULL, NULL);
|
||||||
|
CHECK_RESULT(callback_count, 12);
|
||||||
|
vpi_get_data(0, NULL, 0);
|
||||||
|
CHECK_RESULT(callback_count, 13);
|
||||||
|
vpi_put_data(0, NULL, 0);
|
||||||
|
CHECK_RESULT(callback_count, 14);
|
||||||
|
vpi_get_userdata(NULL);
|
||||||
|
CHECK_RESULT(callback_count, 15);
|
||||||
|
vpi_put_userdata(NULL, NULL);
|
||||||
|
CHECK_RESULT(callback_count, 16);
|
||||||
|
vpi_handle_by_multi_index(NULL, 0, NULL);
|
||||||
|
CHECK_RESULT(callback_count, 17);
|
||||||
|
}
|
||||||
|
return 0; // Ok
|
||||||
|
}
|
||||||
|
|
||||||
|
int mon_check() {
|
||||||
|
// Callback from initial block in monitor
|
||||||
|
if (int status = _mon_check_unimpl(NULL)) return status;
|
||||||
|
return 0; // Ok
|
||||||
|
}
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
|
||||||
|
double sc_time_stamp () {
|
||||||
|
return main_time;
|
||||||
|
}
|
||||||
|
int main(int argc, char **argv, char **env) {
|
||||||
|
double sim_time = 1100;
|
||||||
|
Verilated::commandArgs(argc, argv);
|
||||||
|
Verilated::debug(0);
|
||||||
|
Verilated::fatalOnVpiError(0); // we're going to be checking for these errors do don't crash out
|
||||||
|
|
||||||
|
VM_PREFIX* topp = new VM_PREFIX (""); // Note null name - we're flattening it out
|
||||||
|
|
||||||
|
#ifdef VERILATOR
|
||||||
|
# ifdef TEST_VERBOSE
|
||||||
|
Verilated::scopesDump();
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Verilated::traceEverOn(true);
|
||||||
|
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||||
|
#if VM_TRACE
|
||||||
|
VL_PRINTF("Enabling waves...\n");
|
||||||
|
topp->trace (tfp, 99);
|
||||||
|
tfp->open ("obj_dir/t_vpi_var/simx.vcd");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
topp->eval();
|
||||||
|
topp->clk = 0;
|
||||||
|
main_time += 10;
|
||||||
|
|
||||||
|
while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
|
||||||
|
main_time += 1;
|
||||||
|
topp->eval();
|
||||||
|
VerilatedVpi::callValueCbs();
|
||||||
|
topp->clk = !topp->clk;
|
||||||
|
//mon_do();
|
||||||
|
#if VM_TRACE
|
||||||
|
if (tfp) tfp->dump (main_time);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
CHECK_RESULT(callback_count, 17);
|
||||||
|
if (!Verilated::gotFinish()) {
|
||||||
|
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
|
||||||
|
}
|
||||||
|
topp->final();
|
||||||
|
|
||||||
|
#if VM_TRACE
|
||||||
|
if (tfp) tfp->close();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
delete topp; topp=NULL;
|
||||||
|
exit(0L);
|
||||||
|
}
|
21
test_regress/t/t_vpi_unimpl.pl
Normal file
21
test_regress/t/t_vpi_unimpl.pl
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/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.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
make_top_shell => 0,
|
||||||
|
make_main => 0,
|
||||||
|
verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --no-l2name $Self->{t_dir}/t_vpi_unimpl.cpp"],
|
||||||
|
);
|
||||||
|
|
||||||
|
execute (
|
||||||
|
check_finished=>1
|
||||||
|
);
|
||||||
|
|
||||||
|
ok(1);
|
||||||
|
1;
|
42
test_regress/t/t_vpi_unimpl.v
Normal file
42
test_regress/t/t_vpi_unimpl.v
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
`ifdef VERILATOR
|
||||||
|
//We call it via $c so we can verify DPI isn't required - see bug572
|
||||||
|
`else
|
||||||
|
import "DPI-C" context function integer mon_check();
|
||||||
|
`endif
|
||||||
|
|
||||||
|
module t (/*AUTOARG*/
|
||||||
|
// Inputs
|
||||||
|
clk
|
||||||
|
);
|
||||||
|
|
||||||
|
`ifdef VERILATOR
|
||||||
|
`systemc_header
|
||||||
|
extern "C" int mon_check();
|
||||||
|
`verilog
|
||||||
|
`endif
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
|
||||||
|
reg onebit /*verilator public_flat_rw @(posedge clk) */;
|
||||||
|
|
||||||
|
integer status;
|
||||||
|
|
||||||
|
// Test loop
|
||||||
|
initial begin
|
||||||
|
`ifdef VERILATOR
|
||||||
|
status = $c32("mon_check()");
|
||||||
|
`else
|
||||||
|
status = mon_check();
|
||||||
|
`endif
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule : t
|
@ -28,10 +28,14 @@
|
|||||||
// __FILE__ is too long
|
// __FILE__ is too long
|
||||||
#define FILENM "t_vpi_var.cpp"
|
#define FILENM "t_vpi_var.cpp"
|
||||||
|
|
||||||
|
#define TEST_MSG if (0) printf
|
||||||
|
|
||||||
unsigned int main_time = false;
|
unsigned int main_time = false;
|
||||||
unsigned int callback_count = false;
|
unsigned int callback_count = false;
|
||||||
unsigned int callback_count_half = false;
|
unsigned int callback_count_half = false;
|
||||||
unsigned int callback_count_quad = false;
|
unsigned int callback_count_quad = false;
|
||||||
|
unsigned int callback_count_strs = false;
|
||||||
|
unsigned int callback_count_strs_max = 500;
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
@ -64,15 +68,15 @@ public:
|
|||||||
|
|
||||||
// Use cout to avoid issues with %d/%lx etc
|
// Use cout to avoid issues with %d/%lx etc
|
||||||
#define CHECK_RESULT(got, exp) \
|
#define CHECK_RESULT(got, exp) \
|
||||||
if ((got != exp)) { \
|
if ((got) != (exp)) { \
|
||||||
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__ \
|
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__ \
|
||||||
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
|
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
|
||||||
return __LINE__; \
|
return __LINE__; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_RESULT_HEX(got, exp) \
|
#define CHECK_RESULT_HEX(got, exp) \
|
||||||
if ((got != exp)) { \
|
if ((got) != (exp)) { \
|
||||||
cout<<hex<<"%Error: "<<FILENM<<":"<<__LINE__ \
|
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__<<hex \
|
||||||
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
|
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
|
||||||
return __LINE__; \
|
return __LINE__; \
|
||||||
}
|
}
|
||||||
@ -84,6 +88,9 @@ public:
|
|||||||
return __LINE__; \
|
return __LINE__; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CHECK_RESULT_CSTR_STRIP(got, exp) \
|
||||||
|
CHECK_RESULT_CSTR(got+strspn(got, " "), exp)
|
||||||
|
|
||||||
int _mon_check_mcd() {
|
int _mon_check_mcd() {
|
||||||
PLI_INT32 status;
|
PLI_INT32 status;
|
||||||
|
|
||||||
@ -352,6 +359,213 @@ int _mon_check_quad() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _mon_check_string() {
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
const char *initial;
|
||||||
|
const char *value;
|
||||||
|
} text_test_obs[] = {
|
||||||
|
{"t.text_byte", "B", "xxA"}, // x's dropped
|
||||||
|
{"t.text_half", "Hf", "xxT2"}, // x's dropped
|
||||||
|
{"t.text_word", "Word", "Tree"},
|
||||||
|
{"t.text_long", "Long64b", "44Four44"},
|
||||||
|
{"t.text" , "Verilog Test module", "lorem ipsum"},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i=0; i<5; i++) {
|
||||||
|
VlVpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)text_test_obs[i].name, NULL);
|
||||||
|
CHECK_RESULT_NZ(vh1);
|
||||||
|
|
||||||
|
s_vpi_value v;
|
||||||
|
s_vpi_time t = { vpiSimTime, 0, 0};
|
||||||
|
s_vpi_error_info e;
|
||||||
|
|
||||||
|
v.format = vpiStringVal;
|
||||||
|
vpi_get_value(vh1, &v);
|
||||||
|
if (vpi_chk_error(&e)) {
|
||||||
|
printf("%%vpi_chk_error : %s\n", e.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_RESULT_CSTR_STRIP(v.value.str, text_test_obs[i].initial);
|
||||||
|
|
||||||
|
v.value.str = (PLI_BYTE8*)text_test_obs[i].value;
|
||||||
|
vpi_put_value(vh1, &v, &t, vpiNoDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _mon_check_putget_str(p_cb_data cb_data) {
|
||||||
|
static VlVpiHandle cb;
|
||||||
|
static struct {
|
||||||
|
VlVpiHandle scope, sig, rfr, check, verbose;
|
||||||
|
char str[128+1]; // char per bit plus null terminator
|
||||||
|
int type; // value type in .str
|
||||||
|
union {
|
||||||
|
PLI_INT32 integer;
|
||||||
|
s_vpi_vecval vector[4];
|
||||||
|
} value; // reference
|
||||||
|
} data[129];
|
||||||
|
if (cb_data) {
|
||||||
|
// this is the callback
|
||||||
|
static unsigned int seed = 1;
|
||||||
|
s_vpi_time t;
|
||||||
|
t.type = vpiSimTime;
|
||||||
|
t.high = 0;
|
||||||
|
t.low = 0;
|
||||||
|
for (int i=2; i<=128; i++) {
|
||||||
|
static s_vpi_value v;
|
||||||
|
int words = (i+31)>>5;
|
||||||
|
TEST_MSG("========== %d ==========\n", i);
|
||||||
|
if (callback_count_strs) {
|
||||||
|
// check persistance
|
||||||
|
if (data[i].type) {
|
||||||
|
v.format = data[i].type;
|
||||||
|
} else {
|
||||||
|
static PLI_INT32 vals[] = {vpiBinStrVal, vpiOctStrVal, vpiHexStrVal, vpiDecStrVal};
|
||||||
|
v.format = vals[rand_r(&seed) % ((words>2)?3:4)];
|
||||||
|
TEST_MSG("new format %d\n", v.format);
|
||||||
|
}
|
||||||
|
vpi_get_value(data[i].sig, &v);
|
||||||
|
TEST_MSG("%s\n", v.value.str);
|
||||||
|
if (data[i].type) {
|
||||||
|
CHECK_RESULT_CSTR(v.value.str, data[i].str);
|
||||||
|
} else {
|
||||||
|
data[i].type = v.format;
|
||||||
|
strcpy(data[i].str, v.value.str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for corruption
|
||||||
|
v.format = (words==1)?vpiIntVal:vpiVectorVal;
|
||||||
|
vpi_get_value(data[i].sig, &v);
|
||||||
|
if (v.format == vpiIntVal) {
|
||||||
|
TEST_MSG("%08x %08x\n", v.value.integer, data[i].value.integer);
|
||||||
|
CHECK_RESULT(v.value.integer, data[i].value.integer);
|
||||||
|
} else {
|
||||||
|
for (int k=0; k < words; k++) {
|
||||||
|
TEST_MSG("%d %08x %08x\n", k, v.value.vector[k].aval, data[i].value.vector[k].aval);
|
||||||
|
CHECK_RESULT_HEX(v.value.vector[k].aval, data[i].value.vector[k].aval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback_count_strs & 7) {
|
||||||
|
// put same value back - checking encoding/decoding equivalent
|
||||||
|
v.format = data[i].type;
|
||||||
|
v.value.str = data[i].str;
|
||||||
|
vpi_put_value(data[i].sig, &v, &t, vpiNoDelay);
|
||||||
|
v.format = vpiIntVal;
|
||||||
|
v.value.integer = 1;
|
||||||
|
//vpi_put_value(data[i].verbose, &v, &t, vpiNoDelay);
|
||||||
|
vpi_put_value(data[i].check, &v, &t, vpiNoDelay);
|
||||||
|
} else {
|
||||||
|
// stick a new random value in
|
||||||
|
unsigned int mask = ((i&31)?(1<<(i&31)):0)-1;
|
||||||
|
if (words == 1) {
|
||||||
|
v.value.integer = rand_r(&seed);
|
||||||
|
data[i].value.integer = v.value.integer &= mask;
|
||||||
|
v.format = vpiIntVal;
|
||||||
|
TEST_MSG("new value %08x\n", data[i].value.integer);
|
||||||
|
} else {
|
||||||
|
TEST_MSG("new value\n");
|
||||||
|
for (int j=0; j<4; j++) {
|
||||||
|
data[i].value.vector[j].aval = rand_r(&seed);
|
||||||
|
if (j==(words-1)) {
|
||||||
|
data[i].value.vector[j].aval &= mask;
|
||||||
|
}
|
||||||
|
TEST_MSG(" %08x\n", data[i].value.vector[j].aval);
|
||||||
|
}
|
||||||
|
v.value.vector = data[i].value.vector;
|
||||||
|
v.format = vpiVectorVal;
|
||||||
|
}
|
||||||
|
vpi_put_value(data[i].sig, &v, &t, vpiNoDelay);
|
||||||
|
vpi_put_value(data[i].rfr, &v, &t, vpiNoDelay);
|
||||||
|
}
|
||||||
|
if ((callback_count_strs & 1) == 0) data[i].type = 0;
|
||||||
|
}
|
||||||
|
if (++callback_count_strs == callback_count_strs_max) {
|
||||||
|
int success = vpi_remove_cb(cb);
|
||||||
|
CHECK_RESULT_NZ(success);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// setup and install
|
||||||
|
for (int i=1; i<=128; i++) {
|
||||||
|
char buf[32];
|
||||||
|
snprintf(buf, sizeof(buf), "t.arr[%d].arr", i);
|
||||||
|
CHECK_RESULT_NZ(data[i].scope = vpi_handle_by_name((PLI_BYTE8*)buf, NULL));
|
||||||
|
CHECK_RESULT_NZ(data[i].sig = vpi_handle_by_name((PLI_BYTE8*)"sig", data[i].scope));
|
||||||
|
CHECK_RESULT_NZ(data[i].rfr = vpi_handle_by_name((PLI_BYTE8*)"rfr", data[i].scope));
|
||||||
|
CHECK_RESULT_NZ(data[i].check = vpi_handle_by_name((PLI_BYTE8*)"check", data[i].scope));
|
||||||
|
CHECK_RESULT_NZ(data[i].verbose = vpi_handle_by_name((PLI_BYTE8*)"verbose", data[i].scope));
|
||||||
|
}
|
||||||
|
|
||||||
|
static t_cb_data cb_data;
|
||||||
|
static s_vpi_value v;
|
||||||
|
static VlVpiHandle count_h = vpi_handle_by_name((PLI_BYTE8*)"t.count", NULL);
|
||||||
|
|
||||||
|
cb_data.reason = cbValueChange;
|
||||||
|
cb_data.cb_rtn = _mon_check_putget_str; // this function
|
||||||
|
cb_data.obj = count_h;
|
||||||
|
cb_data.value = &v;
|
||||||
|
v.format = vpiIntVal;
|
||||||
|
|
||||||
|
cb = vpi_register_cb(&cb_data);
|
||||||
|
CHECK_RESULT_NZ(cb);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _mon_check_vlog_info() {
|
||||||
|
s_vpi_vlog_info vlog_info;
|
||||||
|
PLI_INT32 rtn = vpi_get_vlog_info(&vlog_info);
|
||||||
|
CHECK_RESULT(rtn, 1);
|
||||||
|
CHECK_RESULT(vlog_info.argc, 4);
|
||||||
|
CHECK_RESULT_CSTR(vlog_info.argv[1], "+PLUS");
|
||||||
|
CHECK_RESULT_CSTR(vlog_info.argv[2], "+INT=1234");
|
||||||
|
CHECK_RESULT_CSTR(vlog_info.argv[3], "+STRSTR");
|
||||||
|
CHECK_RESULT_CSTR(vlog_info.product, "Verilator");
|
||||||
|
CHECK_RESULT(strlen(vlog_info.version) > 0, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK_ENUM_STR(fn, enum) \
|
||||||
|
do { \
|
||||||
|
const char* strVal = VerilatedVpiError::fn(enum); \
|
||||||
|
CHECK_RESULT_CSTR(strVal, #enum); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
int _mon_check_vl_str() {
|
||||||
|
|
||||||
|
CHECK_ENUM_STR(strFromVpiVal, vpiBinStrVal);
|
||||||
|
CHECK_ENUM_STR(strFromVpiVal, vpiRawFourStateVal);
|
||||||
|
|
||||||
|
CHECK_ENUM_STR(strFromVpiObjType, vpiAlways);
|
||||||
|
CHECK_ENUM_STR(strFromVpiObjType, vpiWhile);
|
||||||
|
CHECK_ENUM_STR(strFromVpiObjType, vpiAttribute);
|
||||||
|
CHECK_ENUM_STR(strFromVpiObjType, vpiUdpArray);
|
||||||
|
CHECK_ENUM_STR(strFromVpiObjType, vpiContAssignBit);
|
||||||
|
CHECK_ENUM_STR(strFromVpiObjType, vpiGenVar);
|
||||||
|
|
||||||
|
CHECK_ENUM_STR(strFromVpiMethod, vpiCondition);
|
||||||
|
CHECK_ENUM_STR(strFromVpiMethod, vpiStmt);
|
||||||
|
|
||||||
|
CHECK_ENUM_STR(strFromVpiCallbackReason, cbValueChange);
|
||||||
|
CHECK_ENUM_STR(strFromVpiCallbackReason, cbAtEndOfSimTime);
|
||||||
|
|
||||||
|
CHECK_ENUM_STR(strFromVpiProp, vpiType);
|
||||||
|
CHECK_ENUM_STR(strFromVpiProp, vpiProtected);
|
||||||
|
CHECK_ENUM_STR(strFromVpiProp, vpiDirection);
|
||||||
|
CHECK_ENUM_STR(strFromVpiProp, vpiTermIndex);
|
||||||
|
CHECK_ENUM_STR(strFromVpiProp, vpiConstType);
|
||||||
|
CHECK_ENUM_STR(strFromVpiProp, vpiAutomatic);
|
||||||
|
CHECK_ENUM_STR(strFromVpiProp, vpiOffset);
|
||||||
|
CHECK_ENUM_STR(strFromVpiProp, vpiStop);
|
||||||
|
CHECK_ENUM_STR(strFromVpiProp, vpiIsProtected);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int mon_check() {
|
int mon_check() {
|
||||||
// Callback from initial block in monitor
|
// Callback from initial block in monitor
|
||||||
if (int status = _mon_check_mcd()) return status;
|
if (int status = _mon_check_mcd()) return status;
|
||||||
@ -361,6 +575,10 @@ int mon_check() {
|
|||||||
if (int status = _mon_check_varlist()) return status;
|
if (int status = _mon_check_varlist()) return status;
|
||||||
if (int status = _mon_check_getput()) return status;
|
if (int status = _mon_check_getput()) return status;
|
||||||
if (int status = _mon_check_quad()) return status;
|
if (int status = _mon_check_quad()) return status;
|
||||||
|
if (int status = _mon_check_string()) return status;
|
||||||
|
if (int status = _mon_check_putget_str(NULL)) return status;
|
||||||
|
if (int status = _mon_check_vlog_info()) return status;
|
||||||
|
if (int status = _mon_check_vl_str()) return status;
|
||||||
return 0; // Ok
|
return 0; // Ok
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,6 +626,7 @@ int main(int argc, char **argv, char **env) {
|
|||||||
CHECK_RESULT(callback_count, 501);
|
CHECK_RESULT(callback_count, 501);
|
||||||
CHECK_RESULT(callback_count_half, 250);
|
CHECK_RESULT(callback_count_half, 250);
|
||||||
CHECK_RESULT(callback_count_quad, 2);
|
CHECK_RESULT(callback_count_quad, 2);
|
||||||
|
CHECK_RESULT(callback_count_strs, callback_count_strs_max);
|
||||||
if (!Verilated::gotFinish()) {
|
if (!Verilated::gotFinish()) {
|
||||||
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
|
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
|||||||
compile (
|
compile (
|
||||||
make_top_shell => 0,
|
make_top_shell => 0,
|
||||||
make_main => 0,
|
make_main => 0,
|
||||||
verilator_flags2 => ["-CFLAGS '-ggdb' --exe --no-l2name $Self->{t_dir}/t_vpi_var.cpp"],
|
verilator_flags2 => ["-CFLAGS '-DVL_DEBUG -ggdb' --exe --no-l2name $Self->{t_dir}/t_vpi_var.cpp"],
|
||||||
);
|
);
|
||||||
|
|
||||||
execute (
|
execute (
|
||||||
check_finished=>1,
|
check_finished=>1,
|
||||||
|
all_run_flags => ['+PLUS +INT=1234 +STRSTR']
|
||||||
);
|
);
|
||||||
|
|
||||||
ok(1);
|
ok(1);
|
||||||
|
@ -33,6 +33,12 @@ extern "C" int mon_check();
|
|||||||
reg [31:0] count /*verilator public_flat_rd */;
|
reg [31:0] count /*verilator public_flat_rd */;
|
||||||
reg [31:0] half_count /*verilator public_flat_rd */;
|
reg [31:0] half_count /*verilator public_flat_rd */;
|
||||||
|
|
||||||
|
reg [7:0] text_byte /*verilator public_flat_rw @(posedge clk) */;
|
||||||
|
reg [15:0] text_half /*verilator public_flat_rw @(posedge clk) */;
|
||||||
|
reg [31:0] text_word /*verilator public_flat_rw @(posedge clk) */;
|
||||||
|
reg [63:0] text_long /*verilator public_flat_rw @(posedge clk) */;
|
||||||
|
reg [511:0] text /*verilator public_flat_rw @(posedge clk) */;
|
||||||
|
|
||||||
integer status;
|
integer status;
|
||||||
|
|
||||||
sub sub();
|
sub sub();
|
||||||
@ -40,6 +46,11 @@ extern "C" int mon_check();
|
|||||||
// Test loop
|
// Test loop
|
||||||
initial begin
|
initial begin
|
||||||
onebit = 1'b0;
|
onebit = 1'b0;
|
||||||
|
text_byte = "B";
|
||||||
|
text_half = "Hf";
|
||||||
|
text_word = "Word";
|
||||||
|
text_long = "Long64b";
|
||||||
|
text = "Verilog Test module";
|
||||||
`ifdef VERILATOR
|
`ifdef VERILATOR
|
||||||
status = $c32("mon_check()");
|
status = $c32("mon_check()");
|
||||||
`else
|
`else
|
||||||
@ -52,6 +63,11 @@ extern "C" int mon_check();
|
|||||||
if (onebit != 1'b1) $stop;
|
if (onebit != 1'b1) $stop;
|
||||||
if (quads[2] != 62'h12819213_abd31a1c) $stop;
|
if (quads[2] != 62'h12819213_abd31a1c) $stop;
|
||||||
if (quads[3] != 62'h1c77bb9b_3784ea09) $stop;
|
if (quads[3] != 62'h1c77bb9b_3784ea09) $stop;
|
||||||
|
if (text_byte != "A") $stop;
|
||||||
|
if (text_half != "T2") $stop;
|
||||||
|
if (text_word != "Tree") $stop;
|
||||||
|
if (text_long != "44Four44") $stop;
|
||||||
|
if (text != "lorem ipsum") $stop;
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
@ -65,9 +81,33 @@ extern "C" int mon_check();
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
genvar i;
|
||||||
|
generate
|
||||||
|
for (i=1;i<=128;i++) begin : arr
|
||||||
|
arr #(.LENGTH(i)) arr();
|
||||||
|
end endgenerate
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
module sub;
|
module sub;
|
||||||
reg subsig1 /*verilator public_flat_rd*/;
|
reg subsig1 /*verilator public_flat_rd*/;
|
||||||
reg subsig2 /*verilator public_flat_rd*/;
|
reg subsig2 /*verilator public_flat_rd*/;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
module arr;
|
||||||
|
|
||||||
|
parameter LENGTH = 1;
|
||||||
|
|
||||||
|
reg [LENGTH-1:0] sig /*verilator public_flat_rw*/;
|
||||||
|
reg [LENGTH-1:0] rfr /*verilator public_flat_rw*/;
|
||||||
|
|
||||||
|
reg check /*verilator public_flat_rw*/;
|
||||||
|
reg verbose /*verilator public_flat_rw*/;
|
||||||
|
|
||||||
|
always @(posedge check) begin
|
||||||
|
if (verbose) $display("%m : %x %x", sig, rfr);
|
||||||
|
if (check && sig != rfr) $stop;
|
||||||
|
check <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule : arr
|
||||||
|
Loading…
Reference in New Issue
Block a user