Add $finish_and_return.
This new system task can be used to set the vvp return value and finish the simulation.
This commit is contained in:
parent
f17db21bf0
commit
608c2574bd
|
|
@ -48,6 +48,93 @@ static PLI_INT32 size_32(PLI_BYTE8* ud)
|
|||
return 32;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Routine to finish the simulation and return a value to the
|
||||
* calling environment.
|
||||
*/
|
||||
static PLI_INT32 finish_and_return_compiletf(PLI_BYTE8* ud)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
vpiHandle arg;
|
||||
(void) ud; /* Not used! */
|
||||
|
||||
/* We must have at least one argument. */
|
||||
if (argv == 0) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("$finish_and_return requires an argument.\n");
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This must be a numeric argument. */
|
||||
arg = vpi_scan(argv);
|
||||
switch(vpi_get(vpiType, arg)) {
|
||||
case vpiConstant:
|
||||
case vpiParameter:
|
||||
/* String constants are invalid numeric values. */
|
||||
if (vpi_get(vpiConstType, arg) == vpiStringConst) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("The argument to $finish_and_return must be numeric.\n");
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case vpiIntegerVar:
|
||||
case vpiMemoryWord:
|
||||
case vpiNet:
|
||||
case vpiRealVar:
|
||||
case vpiReg:
|
||||
case vpiTimeVar:
|
||||
break;
|
||||
|
||||
default:
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("The argument to $finish_and_return must be numeric.\n");
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We can only have one argument. */
|
||||
if (vpi_scan(argv) != 0) {
|
||||
vpi_printf("ERROR: %s line %d: ", vpi_get_str(vpiFile, callh),
|
||||
(int)vpi_get(vpiLineNo, callh));
|
||||
vpi_printf("$finish_and_return takes a single argument.\n");
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PLI_INT32 finish_and_return_calltf(PLI_BYTE8* ud)
|
||||
{
|
||||
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
|
||||
vpiHandle argv = vpi_iterate(vpiArgument, callh);
|
||||
vpiHandle arg;
|
||||
s_vpi_value val;
|
||||
(void) ud; /* Not used! */
|
||||
|
||||
/* Get the return value. */
|
||||
arg = vpi_scan(argv);
|
||||
vpi_free_object(argv);
|
||||
val.format = vpiIntVal;
|
||||
vpi_get_value(arg, &val);
|
||||
|
||||
/* Set the return value. */
|
||||
vpip_set_return_value(val.value.integer);
|
||||
|
||||
/* Now finish. */
|
||||
vpi_control(vpiFinish, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the function with Verilog.
|
||||
*/
|
||||
|
|
@ -55,7 +142,6 @@ void sys_special_register(void)
|
|||
{
|
||||
s_vpi_systf_data tf_data;
|
||||
|
||||
/* Register the single argument functions. */
|
||||
tf_data.type = vpiSysFunc;
|
||||
tf_data.sysfunctype = vpiIntFunc;
|
||||
tf_data.calltf = vvp_cpu_wordsize_calltf;
|
||||
|
|
@ -64,4 +150,12 @@ void sys_special_register(void)
|
|||
tf_data.tfname = "$vvp_cpu_wordsize";
|
||||
tf_data.user_data = 0;
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.calltf = finish_and_return_calltf;
|
||||
tf_data.compiletf = finish_and_return_compiletf;
|
||||
tf_data.sizetf = 0;
|
||||
tf_data.tfname = "$finish_and_return";
|
||||
tf_data.user_data = 0;
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -563,6 +563,7 @@ extern DLLEXPORT void (*vlog_startup_routines[])();
|
|||
/* Format a scalar a la %v. The str points to a 4byte character
|
||||
buffer. The value must be a vpiStrengthVal. */
|
||||
extern void vpip_format_strength(char*str, s_vpi_value*value, unsigned bit);
|
||||
extern void vpip_set_return_value(int value);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
|
|
|
|||
11
vvp/main.cc
11
vvp/main.cc
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001-2007 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2008 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -66,6 +66,12 @@ extern "C" long int lround(double x)
|
|||
#endif
|
||||
|
||||
bool verbose_flag = false;
|
||||
static int vvp_return_value = 0;
|
||||
|
||||
void vpip_set_return_value(int value)
|
||||
{
|
||||
vvp_return_value = value;
|
||||
}
|
||||
|
||||
static char log_buffer[4096];
|
||||
|
||||
|
|
@ -305,6 +311,5 @@ int main(int argc, char*argv[])
|
|||
count_gen_events);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return vvp_return_value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,3 +36,4 @@ vpi_sim_vcontrol
|
|||
vpi_vprintf
|
||||
|
||||
vpip_format_strength
|
||||
vpip_set_return_value
|
||||
|
|
|
|||
Loading…
Reference in New Issue