forked from github/verilator
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 VPI product info, warning calls, etc, bug588. [Rick Porter]
|
||||
|
||||
*** Define SYSTEMVERILOG, SV_COV_START and other IEEE mandated predefines.
|
||||
|
||||
**** Fix pin width mismatch error, bug595. [Alex Solomatnikov]
|
||||
|
@ -455,7 +455,7 @@ clean mostlyclean distclean maintainer-clean::
|
||||
|
||||
distclean maintainer-clean::
|
||||
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 \
|
||||
${srcdir}/*.in ${srcdir}/*.pod
|
||||
|
@ -8,7 +8,7 @@
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[3.845 devel])
|
||||
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])
|
||||
|
||||
|
1
include/.gitignore
vendored
1
include/.gitignore
vendored
@ -1 +1,2 @@
|
||||
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 char* Verilated::t_dpiFilename = "";
|
||||
VL_THREAD int Verilated::t_dpiLineno = 0;
|
||||
struct Verilated::CommandArgValues Verilated::s_args = {0, NULL};
|
||||
|
||||
VerilatedImp VerilatedImp::s_s;
|
||||
|
||||
@ -86,6 +87,7 @@ Verilated::Serialized::Serialized() {
|
||||
s_calcUnusedSigs = false;
|
||||
s_gotFinish = false;
|
||||
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) {
|
||||
s_args.argc = argc;
|
||||
s_args.argv = argv;
|
||||
VerilatedImp::commandArgs(argc,argv);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#ifndef _VERILATED_H_
|
||||
#define _VERILATED_H_ 1 ///< Header Guard
|
||||
|
||||
#include "verilated_config.h"
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include <cassert>
|
||||
@ -229,6 +230,7 @@ private:
|
||||
bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated
|
||||
bool s_gotFinish; ///< A $finish statement executed
|
||||
bool s_assertOn; ///< Assertions are enabled
|
||||
bool s_fatalOnVpiError; ///< Stop on vpi error/unsupported
|
||||
Serialized();
|
||||
} s_s;
|
||||
|
||||
@ -236,6 +238,13 @@ private:
|
||||
static VL_THREAD const char* t_dpiFilename; ///< DPI context filename
|
||||
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:
|
||||
|
||||
// METHODS - User called
|
||||
@ -268,6 +277,9 @@ public:
|
||||
/// Enable/disable assertions
|
||||
static void assertOn(bool flag) { s_s.s_assertOn=flag; }
|
||||
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
|
||||
static void flushCb(VerilatedVoidCb cb);
|
||||
static void flushCall() { if (s_flushCb) (*s_flushCb)(); }
|
||||
@ -275,8 +287,13 @@ public:
|
||||
/// Record command line arguments, for retrieval by $test$plusargs/$value$plusargs
|
||||
static void commandArgs(int 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);
|
||||
|
||||
/// 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
|
||||
/// dpiImport/Export context. This function may change in future
|
||||
/// 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;
|
||||
|
||||
//======================================================================
|
||||
|
||||
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
|
||||
#define FILENM "t_vpi_var.cpp"
|
||||
|
||||
#define TEST_MSG if (0) printf
|
||||
|
||||
unsigned int main_time = false;
|
||||
unsigned int callback_count = false;
|
||||
unsigned int callback_count_half = 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
|
||||
#define CHECK_RESULT(got, exp) \
|
||||
if ((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<<hex<<"%Error: "<<FILENM<<":"<<__LINE__ \
|
||||
if ((got) != (exp)) { \
|
||||
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__<<hex \
|
||||
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
|
||||
return __LINE__; \
|
||||
}
|
||||
@ -84,6 +88,9 @@ public:
|
||||
return __LINE__; \
|
||||
}
|
||||
|
||||
#define CHECK_RESULT_CSTR_STRIP(got, exp) \
|
||||
CHECK_RESULT_CSTR(got+strspn(got, " "), exp)
|
||||
|
||||
int _mon_check_mcd() {
|
||||
PLI_INT32 status;
|
||||
|
||||
@ -352,6 +359,213 @@ int _mon_check_quad() {
|
||||
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() {
|
||||
// Callback from initial block in monitor
|
||||
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_getput()) 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
|
||||
}
|
||||
|
||||
@ -408,6 +626,7 @@ int main(int argc, char **argv, char **env) {
|
||||
CHECK_RESULT(callback_count, 501);
|
||||
CHECK_RESULT(callback_count_half, 250);
|
||||
CHECK_RESULT(callback_count_quad, 2);
|
||||
CHECK_RESULT(callback_count_strs, callback_count_strs_max);
|
||||
if (!Verilated::gotFinish()) {
|
||||
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 (
|
||||
make_top_shell => 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 (
|
||||
check_finished=>1,
|
||||
all_run_flags => ['+PLUS +INT=1234 +STRSTR']
|
||||
);
|
||||
|
||||
ok(1);
|
||||
|
@ -32,6 +32,12 @@ extern "C" int mon_check();
|
||||
|
||||
reg [31:0] 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;
|
||||
|
||||
@ -40,6 +46,11 @@ extern "C" int mon_check();
|
||||
// Test loop
|
||||
initial begin
|
||||
onebit = 1'b0;
|
||||
text_byte = "B";
|
||||
text_half = "Hf";
|
||||
text_word = "Word";
|
||||
text_long = "Long64b";
|
||||
text = "Verilog Test module";
|
||||
`ifdef VERILATOR
|
||||
status = $c32("mon_check()");
|
||||
`else
|
||||
@ -52,6 +63,11 @@ extern "C" int mon_check();
|
||||
if (onebit != 1'b1) $stop;
|
||||
if (quads[2] != 62'h12819213_abd31a1c) $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
|
||||
|
||||
always @(posedge clk) begin
|
||||
@ -65,9 +81,33 @@ extern "C" int mon_check();
|
||||
end
|
||||
end
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=1;i<=128;i++) begin : arr
|
||||
arr #(.LENGTH(i)) arr();
|
||||
end endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
module sub;
|
||||
reg subsig1 /*verilator public_flat_rd*/;
|
||||
reg subsig2 /*verilator public_flat_rd*/;
|
||||
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