WB_FPU - Operational Overview
There is no initialization required for the WB_FPU. As soon as you write an operand value, the calculation and conversion units will be reset – clearing any stored values in the result registers.
Example Code
The following sections provide example code for each of the calculations and conversions supported by the WB_FPU. The coding assumes connection of the device to a 32-bit processor through an Interconnect component (Interconnect / WB_INTERCON), and using the identifier "FPU" when configuring the slave interface therein.
Addition
For addition, simply write the floating-point values for operand A and operand B and read the ADD_RES register (address 2h
) for the result. Remember that if the operands are different in sign, reading this register will actually return the contents of the SUB_RES register.
#define fpu ((volatile float* ) Base_FPU)
#define OP1 fpu[1]
#define OP2 fpu[2]
#define ADD fpu[2]
// add(): returns a + b, negative or positive infinity on overflow
inline float add( float a, float b )
{
OP1 = a;
OP2 = b;
return ADD;
}
Subtraction
For subtraction, simply write the floating-point values for operand A and operand B and read the SUB_RES register (address 3h
) for the result. Remember that if the operands are different in sign, reading this register will actually return the contents of the ADD_RES register.
#define fpu ((volatile float* ) Base_FPU)
#define OP1 fpu[1]
#define OP2 fpu[2]
#define SUB fpu[3]
// sub(): returns a - b, negative or positive infinity on overflow
inline float sub( float a, float b )
{
OP1 = a;
OP2 = b;
return SUB;
}
Multiplication
For multiplication, simply write the floating-point values for operand A and operand B and read the MUL_RES register (address 4h
) for the result.
#define fpu ((volatile float* ) Base_FPU)
#define OP1 fpu[1]
#define OP2 fpu[2]
#define MUL fpu[4]
// mul(): returns a * b, negative or positive infinity on overflow,
// zero on underflow
inline float mul( float a, float b )
{
OP1 = a;
OP2 = b;
return MUL;
}
Division
For division, simply write the floating-point values for operand A and operand B and read the DIV_RES register (address 5h
) for the result.
#define fpu ((volatile float* ) Base_FPU)
#define OP1 fpu[1]
#define OP2 fpu[2]
#define DIV fpu[5]
// div(): return a / b, positive or negative infinity on overflow or
// divide by zero. 0/0 returns NaN. Returns zero on underflow.
inline float div( float a, float b )
{
OP1 = a;
OP2 = b;
return DIV;
}
Involution
To obtain a quick and cheap square of a single floating-point value, simply write the floating-point value to address 3h
– effectively loading the same value for OPA and OPB – and read the MUL_RES register (address 4h
) for the result.
#define fpu ((volatile float* ) Base_FPU)
#define OP12 fpu[3]
#define SQR fpu[4]
// sqr(): returns a * b, positive infinity on overflow or zero on
// underflow
inline float sqr( float a )
{
OP12 = a;
return MUL;
}
Integer to Float Conversion
To convert a 32-bit integer to an IEEE 754 floating-point value, simply write the integer to the address for operand A and read the ITOF_RES register (address 6h
) for the result.
#define fpu ((volatile float* ) Base_FPU)
#define xfpu ((volatile int* ) Base_FPU)
#define OP1 xfpu[1]
#define ITOF fpu[6]
// itof(): returns floating-point equivalent of a.
inline float itof( int a )
{
OP1 = a;
return ITOF;
}
Float to Integer Conversion
To convert an IEEE 754 floating-point value to a 32-bit integer value, simply write the floating-point value to the address for operand A and read the FTOI_RES register (address 7h
) for the result.
#define xfpu ((volatile int* ) Base_FPU)
#define fpu ((volatile float* ) Base_FPU)
#define OP1 fpu[1]
#define FTOI xfpu[7]
// ftoi(): returns integer equivalent of a.
inline float ftoi( int a )
{
OP1 = a;
return FTOI;
}