[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