From a359ec45f790c90279950386ed6dd364abd8f476 Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 20 Jul 2007 10:38:50 -0700 Subject: [PATCH] Pass the finish and stop system task argument correctly. The argument passed to $finish and $stop is not currently used, but it is now passed down to the functions that may someday do something useful with it (schedule_finish() and schedule_stop() in vvp/schedule.cc). --- vpi/sys_finish.c | 57 +++++++++++++++++++++++++++++++++++++++++++----- vvp/vpi_priv.cc | 8 +++++-- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/vpi/sys_finish.c b/vpi/sys_finish.c index b1d231cae..266f35e4d 100644 --- a/vpi/sys_finish.c +++ b/vpi/sys_finish.c @@ -25,14 +25,59 @@ # include "vpi_user.h" # include -static PLI_INT32 sys_finish_calltf(PLI_BYTE8*name) +static PLI_INT32 sys_finish_compiletf(PLI_BYTE8 *name) { - if (strcmp((char*)name,"$stop") == 0) { - vpi_control(vpiStop, 0); + vpiHandle callh = vpi_handle(vpiSysTfCall, 0); + vpiHandle argv = vpi_iterate(vpiArgument, callh); + vpiHandle arg; + + /* The argument is optional. */ + if (argv == 0) return 0; + arg = vpi_scan(argv); + + /* A string diagnostic messege level makes no sense. */ + if (vpi_get(vpiType, arg) == vpiConstant && + vpi_get(vpiConstType, arg) == vpiStringConst) { + vpi_printf("Error: %s does not take a string argument.\n", name); + vpi_control(vpiFinish, 1); + return 0; + } + + /* These functions take at most one argument (diagnostic message). */ + arg = vpi_scan(argv); + if (arg != 0) { + vpi_printf("Error: %s takes at most one argument.\n", name); + vpi_control(vpiFinish, 1); + return 0; + } + + /* vpi_scan returning 0 (NULL) has already freed argv. */ + return 0; +} + +static PLI_INT32 sys_finish_calltf(PLI_BYTE8 *name) +{ + vpiHandle callh, argv, arg; + s_vpi_value val; + long diag_msg = 1; + + /* Get the argument list and look for the diagnostic message level. */ + callh = vpi_handle(vpiSysTfCall, 0); + argv = vpi_iterate(vpiArgument, callh); + if (argv) { + arg = vpi_scan(argv); + vpi_free_object(argv); + val.format = vpiIntVal; + vpi_get_value(arg, &val); + diag_msg = val.value.integer; + } + + if (strcmp((char*)name, "$stop") == 0) { + vpi_control(vpiStop, diag_msg); return 0; } - vpi_control(vpiFinish, 0); + vpi_control(vpiFinish, diag_msg); return 0; } @@ -43,7 +88,7 @@ void sys_finish_register() tf_data.type = vpiSysTask; tf_data.tfname = "$finish"; tf_data.calltf = sys_finish_calltf; - tf_data.compiletf = 0; + tf_data.compiletf = sys_finish_compiletf; tf_data.sizetf = 0; tf_data.user_data = (PLI_BYTE8*)"$finish"; vpi_register_systf(&tf_data); @@ -51,7 +96,7 @@ void sys_finish_register() tf_data.type = vpiSysTask; tf_data.tfname = "$stop"; tf_data.calltf = sys_finish_calltf; - tf_data.compiletf = 0; + tf_data.compiletf = sys_finish_compiletf; tf_data.sizetf = 0; tf_data.user_data = (PLI_BYTE8*)"$stop"; vpi_register_systf(&tf_data); diff --git a/vvp/vpi_priv.cc b/vvp/vpi_priv.cc index a1739ef4d..57b507eae 100644 --- a/vvp/vpi_priv.cc +++ b/vvp/vpi_priv.cc @@ -833,13 +833,17 @@ extern "C" PLI_INT32 vpi_flush(void) extern "C" void vpi_sim_vcontrol(int operation, va_list ap) { + long diag_msg; + switch (operation) { case vpiFinish: - schedule_finish(0); + diag_msg = va_arg(ap, long); + schedule_finish(diag_msg); break; case vpiStop: - schedule_stop(0); + diag_msg = va_arg(ap, long); + schedule_stop(diag_msg); break; default: