mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-09-01 10:16:40 +02:00
By adding ivtest to the iverilog source tree, it is easier to keep the regression test synchronized with the source that is being tested. This should be especially helpful for PRs that add a new feature, and have a matching ivtest PR with the regression test for that feature.
115 lines
3.1 KiB
C
115 lines
3.1 KiB
C
/*
|
|
* This test verifies the the vpi_get_vlog_info() call returns the
|
|
* version information correctly. This does not currently work in
|
|
* V0.8 so it is marked NI.
|
|
*/
|
|
#include "vpi_user.h"
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
static PLI_INT32 compiletf(PLI_BYTE8 *name)
|
|
{
|
|
vpiHandle callh, argv, arg;
|
|
callh = vpi_handle(vpiSysTfCall, 0);
|
|
argv = vpi_iterate(vpiArgument, callh);
|
|
|
|
/* Check that there is an argument. */
|
|
if (argv == 0) {
|
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
|
(int)vpi_get(vpiLineNo, callh));
|
|
vpi_printf("%s() requires a single vector argument!", name);
|
|
vpi_control(vpiFinish, 1);
|
|
return 0;
|
|
}
|
|
arg = vpi_scan(argv);
|
|
if (arg == 0) {
|
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
|
(int)vpi_get(vpiLineNo, callh));
|
|
vpi_printf("%s() requires a single vector argument!", name);
|
|
vpi_control(vpiFinish, 1);
|
|
return 0;
|
|
}
|
|
|
|
/* Check that the argument is a register with at least 640 bits. */
|
|
if (vpi_get(vpiType, arg) != vpiReg) {
|
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
|
(int)vpi_get(vpiLineNo, callh));
|
|
vpi_printf("%s() requires a vector argument!", name);
|
|
vpi_free_object(argv);
|
|
vpi_control(vpiFinish, 1);
|
|
return 0;
|
|
}
|
|
if (vpi_get(vpiSize, arg) < 640) {
|
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
|
(int)vpi_get(vpiLineNo, callh));
|
|
vpi_printf("%s() vector is too small need 640 bits!", name);
|
|
vpi_free_object(argv);
|
|
vpi_control(vpiFinish, 1);
|
|
return 0;
|
|
}
|
|
|
|
/* We only take one argument. */
|
|
arg = vpi_scan(argv);
|
|
if (arg != 0) {
|
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
|
(int)vpi_get(vpiLineNo, callh));
|
|
vpi_printf("%s() only takes one argument!", name);
|
|
vpi_free_object(argv);
|
|
vpi_control(vpiFinish, 1);
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static PLI_INT32 calltf(PLI_BYTE8 *name)
|
|
{
|
|
vpiHandle callh, argv, reg;
|
|
s_vpi_vlog_info info;
|
|
s_vpi_value val;
|
|
PLI_INT32 ret;
|
|
char *str, *cp;
|
|
|
|
callh = vpi_handle(vpiSysTfCall, 0);
|
|
argv = vpi_iterate(vpiArgument, callh);
|
|
reg = vpi_scan(argv);
|
|
vpi_free_object(argv);
|
|
|
|
/* Get the Verilog version information. */
|
|
ret = vpi_get_vlog_info(&info);
|
|
if (ret == 0) {
|
|
vpi_printf("ERROR: %s:%d: ", vpi_get_str(vpiFile, callh),
|
|
(int)vpi_get(vpiLineNo, callh));
|
|
vpi_printf("%s() failed to get verilog information!", name);
|
|
vpi_control(vpiFinish, 1);
|
|
}
|
|
|
|
/* For Icarus we can just return everything before the space to
|
|
* get the version and subversion. */
|
|
str = strdup(info.version);
|
|
cp = strchr(str, ' ');
|
|
if (cp)
|
|
*cp = '\0';
|
|
val.format = vpiStringVal;
|
|
val.value.str = str;
|
|
vpi_put_value(reg, &val, 0, vpiNoDelay);
|
|
free(str);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void my_register(void)
|
|
{
|
|
s_vpi_systf_data tf_data;
|
|
|
|
tf_data.type = vpiSysTask;
|
|
tf_data.tfname = "$get_version";
|
|
tf_data.calltf = calltf;
|
|
tf_data.compiletf = compiletf;
|
|
tf_data.sizetf = 0;
|
|
tf_data.user_data = "$get_version";
|
|
vpi_register_systf(&tf_data);
|
|
}
|
|
|
|
void (*vlog_startup_routines[]) (void) = { my_register, 0};
|