Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

How to write floating-point value to custom logic???

Hi all,

I worte a component which is using altfp_sqrt of megafunction, then I checked the simulation with avalon interface signal, it's match the timing and need 17 cycles. All configurations are set in sopc. BUT in nios, when I wrote the floating-point data using IOWR, the sqrt component did not compute. My code is under below

# include <stdio.h># include <float.h># include <unistd.h># include "system.h"

int main()

{

float data_in = 2.0;

float ans;

IOWR(SQRT_BASE, 0, data_in); //regnum = 0 is data_in

usleep(1);//because 17 cycle delay

ans = IORD(SQRT_BASE, 1); //regnum = 1 is calculate result

printf("%f\n", ans);

return 0;

}

The value will show 0.000000

If I change the data format such like this:

unsigned in data_in = 0x40000000; //IEEE-754 format, equivalence 2.0

unsigned int ans;

So, I can get the correct value, but the data type is NOT floating-point

If I want to use custom logic to calculate floating-point in NIOS, how to solve this problem???

thanks all

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hello,

    You can use a function to copy hexadecimal values using the address like that :

    
    unsigned long F32ToHex (float valueF)
    {
        unsigned long* valueL = (unsigned long*) &valueF;
        return *valueL;
    }
    And you call it as following :

    
    float value = 678.482;
    unsigned long hexValue;
    hexValue = F32ToHex(value);
    IOWR(SQRT_BASE, 0, hexValue);
    
    Jérôme
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Except that such code breaks the 'strict aliasing' rules of C, and gcc might optimise away the assignment.

    Better would be a cast on the LHS, eg:

    *(volatile float *)SQRT_BASE = data_in;

    An alternative is to define a C structure, and variable of a type that matches the IO device, and then get the linker to assign a fixed address (or use a pointer). eg:

    
    extern struct {
        volatile float  sqrt_in;
        volatile float  sqrt_out;
    } *sqrt_device = (void *)(1u << 31 | SQRT_BASE);
        ...
        sqrt_device->sqrt_in = data_in;
        delay();
        printf("%f\n", sqrt_device->sqrt_out);
    

    IMHO using structures to access hardware devices is much less error prone than trying to use constants and access macros.

    Although not 100% portable, it is portable enough.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    THANKS LETS and dsl!!!

    My problem SOLVED TOTALLY!!!

    The function work out fine!!!

    Thank you very much!!!