cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
alexandre.solon
Visitor
Visitor
14,899 Views
Registered: ‎11-20-2008

Microblaze Floating Point Representation

Jump to solution

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. 

0 Kudos
1 Solution

Accepted Solutions
alexandre.solon
Visitor
Visitor
18,378 Views
Registered: ‎11-20-2008

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!

 

Message Edited by alexandre.solon on 11-16-2009 07:37 AM

View solution in original post

0 Kudos
10 Replies
brianhill
Xilinx Employee
Xilinx Employee
14,884 Views
Registered: ‎04-23-2008
The compiler has probably not done the most intelligent job of type conversion.  Try this instead: 
 
printf("0x%08x %f\n\r", *(unsigned*)(&f), f);
 
-Brian
 

alexandre.solon
Visitor
Visitor
14,881 Views
Registered: ‎11-20-2008

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.

 

0 Kudos
alexandre.solon
Visitor
Visitor
18,379 Views
Registered: ‎11-20-2008

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!

 

Message Edited by alexandre.solon on 11-16-2009 07:37 AM

View solution in original post

0 Kudos
pumaju1808
Scholar
Scholar
14,797 Views
Registered: ‎08-14-2007

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
0 Kudos
pumaju1808
Scholar
Scholar
14,796 Views
Registered: ‎08-14-2007

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??

 

 

0 Kudos
goran
Xilinx Employee
Xilinx Employee
14,794 Views
Registered: ‎08-06-2007

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

Message Edited by goran_bilski on 11-20-2009 09:55 AM
0 Kudos
pumaju1808
Scholar
Scholar
14,780 Views
Registered: ‎08-14-2007

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

0 Kudos
alexandre.solon
Visitor
Visitor
14,775 Views
Registered: ‎11-20-2008

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);

0 Kudos
pumaju1808
Scholar
Scholar
14,770 Views
Registered: ‎08-14-2007

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

0 Kudos
alexandre.solon
Visitor
Visitor
4,370 Views
Registered: ‎11-20-2008

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):

 

Floating Point Operator V5.0

 

I hope that it can be helpful,

0 Kudos