From: Stephen W. <st...@ic...> - 2019-10-14 20:59:46
|
Great, but we don't want to lose the capability to inline functions like $pow() in the compiler. Some people use this sort of thing to calculate such compile-time constants as, for example, array vector sizes. In general, it is considered poor form to directly replace such basic system functions, especially if that replacement leads to a different prototype. On Mon, Oct 14, 2019 at 7:03 AM Martin Whitaker <ic...@ma...> wrote: > > 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 > > > > > > _______________________________________________ > Iverilog-devel mailing list > Ive...@li... > https://lists.sourceforge.net/lists/listinfo/iverilog-devel -- Steve Williams "The woods are lovely, dark and deep. st...@ic... But I have promises to keep, http://www.icarus.com and lines to code before I sleep, http://www.picturel.com And lines to code before I sleep." |