From: Martin W. <ic...@ma...> - 2019-10-14 14:03:19
|
Hi Yong, My apologies. I looked in the test suite for something to adapt to reproduce the problem, found that, and didn't read it carefully enough! If the compiler detects that a system function has constant arguments, it will try to evaluate it at compile time, using a built-in implementation. That is why your first call works. We should fix that. The second call fails because the compiler is using the return type for the built-in implementation (real) rather than the return type of the replacement (32 bits). There is supposed to be a method of fixing that, by suppling the compiler with a ".sft" file that provides the return types of user-defined system functions, but that also appears to be broken in this case. I'll look into that. Martin On 14/10/19 08:23, fuyong wrote: > Hi, Martin, > > Finally figure out the reason. In the original example, the 1999 version I > have, intention of the test is to override the system defined function, > such as $pow. In your example, you used $my_pow() instead. Guess that in > Iverilog, system defined function calls could not be overwritten yet. > Actually I did noticed in my test with $pow(), the first $pow() called the > system pre-defined function, the second one goes to user defined function. > This is why the first $pow() passed, and the second one get error. > > The version I have is: > version 11.0 (devel) (s20150603-641-ga8318db2) > > Many thanks for the help! > > Yong > > > > On Sun, Oct 13, 2019 at 2:29 AM Martin Whitaker < > ic...@ma...> wrote: > >> I can't reproduce the failure. We have that example in the test suite >> already - see >> >> https://github.com/steveicarus/ivtest/blob/master/vpi/pr1693971.c >> https://github.com/steveicarus/ivtest/blob/master/vpi/pr1693971.v >> >> Please tell us what version of iverilog you are using, and what changes >> you >> have made to the example. Just changing the type of 'result' to 'int' made >> no difference for me. >> >> fuyong wrote: >>> Hi, >>> >>> This is a test in Stuart Sutherland's PLI handbook, and it works well >> with >>> commercial tools. In Iverilog, we can have compile done, but run time >> show: >>> >>> $pow(2, 3) returns 8 >>> Unsupported format 6. >>> vvp: vpi_tasks.cc:179:virtual __vpiHandle* >>> sysfunc_real::vpi_put_value(p_vpi_value, int): Assertion `0` failed. >>> >>> There are two $pow() calls .First one returns correct result, second one >>> failed. with vpi_print, we find seems like the first pow() did not even >>> called our defined function (might be using the $pow in build-in >> $pow()?). >>> Any way, "result" is defined as int, not sure why the assertion is >> trigger >>> in run time. >>> >>> >>> >>> === Verilog side: >>> initial >>> begin >>> a = 1; >>> b = 0; >>> #1 $display("$pow(2,3) returns %d", $pow(2,3)); >>> #1 result = $pow(a,b); >>> #1 $display("$pow(a,b) returns %d (a=%d b=%d)", result, a, b); >>> >>> === C side: >>> >>> tf_data.type = vpiSysFunc; >>> tf_data.sysfunctype = vpiSysFuncSized; >>> tf_data.tfname = "$pow"; >>> tf_data.calltf = PLIbook_PowCalltf; >>> tf_data.compiletf = PLIbook_PowCompiletf; >>> tf_data.sizetf = PLIbook_PowSizetf; >>> vpi_register_systf(&tf_data); >>> >>> >>> int PLIbook_PowCalltf(char *user_data) >>> { >>> s_vpi_value value_s; >>> vpiHandle systf_handle, arg_itr, arg_handle; >>> int base, exp, result; >>> >>> systf_handle = vpi_handle(vpiSysTfCall, NULL); >>> arg_itr = vpi_iterate(vpiArgument, systf_handle); >>> if (arg_itr == NULL) { >>> vpi_printf("ERROR: $pow failed to obtain systf arg handles\n"); >>> return(0); >>> } >>> >>> /* read base from systf arg 1 (compiletf has already verified) */ >>> arg_handle = vpi_scan(arg_itr); >>> value_s.format = vpiIntVal; >>> vpi_get_value(arg_handle, &value_s); >>> base = value_s.value.integer; >>> >>> /* read exponent from systf arg 2 (compiletf has already verified) */ >>> arg_handle = vpi_scan(arg_itr); >>> vpi_free_object(arg_itr); /* not calling scan until returns null */ >>> vpi_get_value(arg_handle, &value_s); >>> exp = value_s.value.integer; >>> >>> /* calculate result of base to power of exponent */ >>> result = (int)pow( (double)base, (double)exp ); >>> >>> /* write result to simulation as return value $pow */ >>> value_s.value.integer = result; >>> vpi_put_value(systf_handle, &value_s, NULL, vpiNoDelay); >>> return(0); >>> } >>> >>> >>> >>> >>> >>> _______________________________________________ >>> Iverilog-devel mailing list >>> Ive...@li... >>> https://lists.sourceforge.net/lists/listinfo/iverilog-devel >>> >> >> >> >> _______________________________________________ >> Iverilog-devel mailing list >> Ive...@li... >> https://lists.sourceforge.net/lists/listinfo/iverilog-devel >> > > > > > > _______________________________________________ > Iverilog-devel mailing list > Ive...@li... > https://lists.sourceforge.net/lists/listinfo/iverilog-devel > |