[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
gEDA-user: Reeling over Reals
Hello again.
I'm completely confused.
Please bear with me.
I have defined with the VPI a task
that computes the square root
of a real input to produce a
real output.
The task is called $FloatSqrt and it
is defined thusly:
static PLI_INT32 calltf_FloatSqrt(PLI_BYTE8* user)
{
vpiHandle callHandle,
argHandles,
argHandle;
s_vpi_value argValue;
/* get input handle */
callHandle = vpi_handle(vpiSysTfCall, 0);
argHandles = vpi_iterate(vpiArgument, callHandle);
argHandle = vpi_scan(argHandles);
/* get input value */
argValue.format = vpiRealVal;
vpi_get_value(argHandle, &argValue);
/* compute square root */
argValue.value.real = sqrt(argValue.value.real);
/* get ouput handle */
argHandle = vpi_scan(argHandles);
/* set output value */
vpi_put_value(argHandle, &argValue, 0, vpiNoDelay);
/* free iterator */
vpi_free_object(argHandles);
return 0;
}
I then make use of this somewhat as follows:
module FloatSqrt
(
input clk,
input [63:0] arg1,
output [63:0] result
);
parameter delay = 11;
real resultReal;
always @ (arg1) $FloatSqrt($bitstoreal(arg1), resultReal);
Delay #(.delay(delay), .width(64)) delayResult
(
clk,
$realtobits(resultReal1),
result
);
endmodule
This compiles fine, but I get the following error when it is run:
VCD info: dumpfile dump.vcd opened for output.
../../src/vvp/vpi_tasks.cc:580: failed assertion `vpi_mode_flag
== VPI_MODE_NONE'
Abort trap
So, I modified vpi_tasks.cc as follows:
if (vpip_cur_task->defn->info.calltf) {
printf("*%d*\n", vpi_mode_flag);
assert(vpi_mode_flag == VPI_MODE_CALLTF);
vpi_mode_flag = VPI_MODE_CALLTF;
vpip_cur_task->defn->info.calltf(vpip_cur_task->defn-
>info.user_data);
vpi_mode_flag = VPI_MODE_NONE;
}
which shows that the problem occurs when vpi_mode_flag ==
VPI_MODE_CALLTF.
Indeed, a further modification:
if (vpip_cur_task->defn->info.calltf) {
printf("*===>%s*\n", vpip_cur_task->defn->info.tfname);
assert(vpi_mode_flag == VPI_MODE_NONE);
vpi_mode_flag = VPI_MODE_CALLTF;
vpip_cur_task->defn->info.calltf(vpip_cur_task->defn-
>info.user_data);
printf("*%s===>*\n", vpip_cur_task->defn->info.tfname);
vpi_mode_flag = VPI_MODE_NONE;
}
reveals that $realtobits is being called before $FloatSqrt exits:
*===>$realtobits*
*$realtobits===>*
*===>$dumpvars*
VCD info: dumpfile dump.vcd opened for output.
*$dumpvars===>*
*===>$bitstoreal*
*$bitstoreal===>*
*===>$FloatSqrt*
*===>$realtobits*
../../src/vvp/vpi_tasks.cc:581: failed assertion `vpi_mode_flag
== VPI_MODE_NONE'
Abort trap
Is this a threading issue?
In any case, I ran gdb and got this backtrace:
#0 0x900484cc in kill ()
#1 0x9012e934 in abort ()
#2 0x0004d760 in __eprintf () at ../../src/vvp/vpi_memory.cc:333
#3 0x00044ae0 in vpip_execute_vpi_call (thr=0x0, ref=0x0)
at ../../src/vvp/vpi_tasks.cc:580
#4 0x0002e318 in vvp_send_real (ptr=@0xbfffece0,
val=1.7735839421916291) at ../../src/vvp/vvp_net.cc:184
#5 0x0002e674 in vvp_fun_signal_real::recv_real (this=0x501ac0,
ptr=@0xbfffed58, bit=1.7735839421916291) at ../../src/vvp/vvp_net.cc:
1769
#6 0x0002e318 in vvp_send_real (ptr=@0xbfffedc8,
val=1.7735839421916291) at ../../src/vvp/vvp_net.cc:184
#7 0x00042880 in real_var_put_value (ref=0x0, vp=0x0) at ../../
src/vvp/vpi_real.cc:76
#8 0x00040c1c in vpi_put_value (obj=0x5017e0, vp=0xbfffee88,
when=0xa0004170, flags=9994) at ../../src/vvp/vpi_priv.cc:618
#9 0x002fcd94 in calltf_FloatSqrt (user=0x0) at FloatSqrt.c:58
#10 0x00044b00 in vpip_execute_vpi_call (thr=0x0, ref=0x0)
at ../../src/vvp/vpi_tasks.cc:582
#11 0x0001c4b4 in of_VPI_CALL (thr=0x503160, cp=0x0) at ../../
src/vvp/vthread.cc:3286
#12 0x0001b8a4 in vthread_run (thr=0x503160) at ../../src/vvp/
vthread.cc:330
#13 0x000279cc in schedule_simulate () at ../../src/vvp/
schedule.cc:634
#14 0x000047a8 in main (argc=6, argv=0xbffff200) at ../../src/
vvp/main.cc:279
However, the flow I was getting in the
debugger didn't make much sense to me.
I noticed that my verilog simulation
runs without error (but incorrectly)
when I remove from the VPI code either
vpi_put_value(...)
or
the second vpi_scan(...)
Yet, removing the latter simply
assigns the sqrt value to the input,
and even that doesn't actually occur,
because the input handle does not have
the proper put handler; the put is just
swallowed without warning.
Curiously, the problem is completely
bypassed when I unnecessarily assign
the output of $FloatSqrt to a temporary
variable and then use that temporary
variable as the input to delayResult.
module FloatSqrt
(
input clk,
input [63:0] arg1,
output [63:0] result
);
parameter delay = 11;
real resultReal1, resultReal2;
always @ (arg1)
begin
$FloatSqrt($bitstoreal(arg1), resultReal1);
resultReal2 = resultReal1;
end
Delay #(.delay(delay), .width(64)) delayResult
(
clk,
$realtobits(resultReal2),
result
);
endmodule
How can I avoid these shenanigans?
Thanks.
_______________________________________________
geda-user mailing list
geda-user@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user