11-11-2009 08:14 AM
Hi everyone,
I have an IP design which needs some floating point input values in order to produce results.
However, I'm not sure what kind of FP representation is being used by Microblaze. For example:
float x = 1.0f;
xil_printf(" 0x%08x \r\n",x);
The output should be 3F800000, instead of 3FF00000.
The Microblaze manual says that floating point numbers are in IEEE 754 Single Precision Format,
but as far as I know the above result should be 3F800000.
Could someone please help me?
What am I missing here?
Thanks in advance...
EDK 11.1 + Virtex 5 ML507.
11-16-2009 07:37 AM - edited 11-16-2009 07:37 AM
Solved!
The idea is to declare an union:
union ufloat
{
float f;
unsigned u;
} x;
then:
x.f = 1.0f;
xil_printf(" %08x ",x.u);
The output is correct: 3F800000
Also, any data that should be passed through FSL (or PLB, etc) must be assigned as follows:
unsigned int input[8];
input[0] = x.u; // the unsigned representation
That is it!
11-11-2009 10:03 AM
11-11-2009 10:17 AM
Hello Brian,
Thanks for your reply...
Still, no sucess.
The major problem is that Microblaze seems to be performing Double Precision operations.
Example:
float input[8];
float output[8];
input[0[ = 0.0F;
input[1] = 2.0F;
input[2] = 2.0F;
etc...
my_fsl(
XPAR_MY_FSL_FSL_0_INPUT_SLOT_ID,
XPAR_MY_FSL_FSL_0_OUTPUT_SLOT_ID,
input,
output
);
The result that I am getting is incorret.
However, the following works:
unsigned int input[8];
unsigned int output[8];
input[0[ = 0x00000000;
input[1] = 0x40000000;
input[2] = 0x40000000;
etc...
my_fsl(
XPAR_MY_FSL_FSL_0_INPUT_SLOT_ID,
XPAR_MY_FSL_FSL_0_OUTPUT_SLOT_ID,
input,
output
);
Then the expected result is correct.
11-16-2009 07:37 AM - edited 11-16-2009 07:37 AM
Solved!
The idea is to declare an union:
union ufloat
{
float f;
unsigned u;
} x;
then:
x.f = 1.0f;
xil_printf(" %08x ",x.u);
The output is correct: 3F800000
Also, any data that should be passed through FSL (or PLB, etc) must be assigned as follows:
unsigned int input[8];
input[0] = x.u; // the unsigned representation
That is it!
11-19-2009 06:44 PM
why the union representation??, i think the right way is that if a number is float then is single precision(32 bits) and if the number is double then is double precision(64 bits), is not??
so if i have a 32-bit FPU and a 64-bit FPU, both made them with core generator, how can i provide right values for each one from microblaze application??
how can i obtain a double precision representation (64 bit)??
double a=1.0; ??
thanks for your attention
best regards
11-19-2009 06:52 PM
by the way,
1.0 in single precision is 3F800000 and
1.0 in double precision is 3FF00000
and when i do this:
float a=1.0;
double b=1.0;
xil_printf("a = %x",a);
xil_printf("b = %x",b);
in BOTH cases i got 3FF00000, so microblaze always use double-precision representation??, but if is double-precision it must be a number of 64 bits right?? (i.e. 3FF0000000000000)
so i am confuse!!!
how i get a single precision number (32-bit) and how i get a double precision number (64-bit) in microblaze??
11-20-2009 12:46 AM - edited 11-20-2009 12:55 AM
Hi,
By default all constants are double-precision unless specified as single-precision.
So to get single-precision constant you should add 'f' to the constant.
Like this:
float a=1.0f;
Furthermore printf will always convert all float to double precision before printing.
So If you want to print a single-precision, you need to convert the single precision to integer before calling printf.
Göran
11-20-2009 08:55 AM
thanks for the reply,
how i convert single precision to integer, with a cast???
float a=3.2f;
xil_printf("a = %x",(int)a);
i only have the integer part of a, i did not get that part
the sinle representation of 3.2 in hexadecimal is 0x404CCCCD, how can i print that value??
thanks in advance
11-20-2009 09:16 AM
Hi pumaju,
"Unions allow one same portion of memory to be accessed as different data types, since all of them are in fact the same location in memory." (from cplusplus.com)
In my case, it worked.
union my_union
{
float f;
unsigned u;
}a;
a.f = 1.0f;
xil_printf("a = %x",a.u);
If you need 64-bit floating point, then:
union my_union
{
double d;
unsigned long u;
}a;
a.d = 1.0;
xil_printf("a = %x",a.u);
11-20-2009 10:47 AM
thanks Alexandre, now i can view my single precision number
well now i want to view the single precision number that my FPU (made with core generator) , i got correctly the hexadecimal representation of my resul, i mean, my result in decimal is 4.515625 and its single representation is 0x40908000, so when i print "fval" variable i get 0x40908000, so that is correct, but when i try to print "4.515625" using whole and thousandths variables i got a rare number, how can i print "4.515625"???
float fval;
fval = FPU_MULT_IP_mReadReg(MULT_ADD,REG1);
xil_printf("\r\nResHW=%x",(u32)fval);
whole = fval;
thousandths = (fval - whole) * 1000;
xil_printf("\r\nResHW=%d.%3d\n", whole, thousandths);
thanks
11-22-2009 05:47 PM
Hi pumaju,
I haven't tried to print floating-point values, yet. (Only in hexa).
I guess that xil_printf("%f", fval.f) should have worked (with fval as a union).
Just in case, take a look at the floating point operator data sheet (page 19):
I hope that it can be helpful,