Power function in vhdl - vhdl

I want to make power function using vhdl where the power is floating number and the number is integer (will be always "2").
2^ some floating number.
I use ieee library and (fixed_float_types.all, fixed_pkg.all, and float_pkg.all).
I thought of calculating all the possible outputs and save them in ROM, but i don't know the ranges of the power.
How to implement this function and if there is any implemented function like this where to find it?
thanks

For simulation, you will find suitable power functions in the IEEE.math_real library
library IEEE;
use IEEE.math_real.all;
...
X <= 2 ** Y;
or
X <= 2.0 ** Y;
This is probably not synthesisable. If I needed a similar operation for synthesis, I would use a lookup table of values, slopes and second derivatives, and a quadratic interpolator. I have used this approach for reciprocal and square root functions to single precision accuracy; 2**n over a reasonable range of n is smooth enough that the same approach should work.

If an approximation would do, I think I would use the integer part of my exponent to determine the integer power of 2, like if the floating point number is 111.011010111 You know that the integer power of 2 part is 0b10000000. Then I would do a left to right conditional add based on the fractional bit, so for 111.011010111 you know you need to add implement 0b10000000 times ( 0*(1/2) + 1*(1/4) + 1*(1/8) + 0*(1/16).....and so on). 1/2, 1/4, 1/8, et cetera are right shifts of 0b10000000. This implements the integer part of the exponentiation, and then approximates the fractional part as multiplication of the integer part.

As simple as any, 0.1 in binary is equivalent to 0.5 in decimal and that is equivalent to calculating a square root.
I've been working on floating point numbers and it took about 4-5 hours to figure this out for implementation of power function in the most simple and synthesizeable way. Just go on with repeated square roots like for b"0.01" you want to do double square root like sqrt(sqrt(x)) and for b"0.11" sqrt * double sqrt like sqrt(x)*sqrt(sqrt(x)) and so on...
This is a synthesizeable implementation of pow function...

Related

Fractional Exponentiation in Forth

I'm trying to write a function that fits a value to a model.
I have a measurement from a pressure sensor and using a calibrated model I have to convert the value into the final pressure management. Doing so involves raising the measurement to a fractional power, in this case x^2.032.
I'm writing this in Mecrisp Stellaris, a dialect of Forth.
I'm a bit stuck. I understand 2.032 = 254/125, but is there a cleaner way to write things than to simply take a huge power and a huge root?
If your language (or calculator) has square-root, then ypu can use that to compute any power. Of course if the language has a power function, it would be better (simpler, faster, more accurate) to use that.
For example to compute
pow( x, 2.032)
we first expand 2.032 as a binary fraction (for example by looking at it in floating point in hex) as
1.032 = 2 + 1/pow(2,5) + 1/pow(2,11) + 1/pow(2,12)
Thus
pow( x, 2.032) = pow(x,2) * pow( x, 1/pow(2,5)) * ...
We can compute
pow( x, 1/pow(2,5))
by starting with x and taking 5 square roots in succession.
The general method is to loop over the binary expansion of 2.032, taking square roots, and accumulating into the answer when the binary digit is 1

What are all the situations in which Fortran outputs NaN?

I know that division by zero and square root of negative real number outputs NaN. Are there any other similar problems?
I will refer to the wikipedia entry on NaN and to Fortran Standard to try to enumerate them.
There are three kinds of operations that can return NaN:[5]
Operations with a NaN as at least one operand.
In Fortran that would include the application of arithmetic and comparisson operators, plus math intrinsic functions.
Indeterminate forms:
The divisions (±0) / (±0) and (±∞) / (±∞).
The multiplications (±0) × (±∞) and (±∞) × (±0).
The additions (+∞) + (−∞), (−∞) + (+∞) and equivalent subtractions (+∞) − (+∞) and (−∞) − (−∞).
The standard has alternative functions for powers:
The standard pow function and the integer exponent pown function define 0⁰, 1∞, and ∞⁰ as 1.
The powr function defines all three indeterminate forms as invalid operations and so returns NaN.
So, all arithmetic operators are included (and also atomic operation functions) . All this was pretty obvious, the fun is next:
Real operations with complex results, for example:
The square root of a negative number.
The logarithm of a negative number.
The inverse sine or cosine of a number that is less than −1 or greater than 1.
That would mean (as said by #kvantour in the comments) any intrinsic function called out of its domain: SQRT, LOG, ATAN, ATAN2, ACOS, ACOSH, ASIN, ASINH, FRACTION, RRSPACING, SET_EXPONENT, SPACING

Easiest way to do VHDL floating point division?

I'm looking for easiest way to divide two floating point numbers using VHDL. I need the code to be synthesizable (I'll be implementing it on Spartan 3 FPGA).
First operand will always be a fixed number (e.g. 600), and second one will be integer, let's say between 0 and 99999. Fixed number is dividend, and the integer one is divisor. So I'll have to calculate something like this: 600/124.
Or any other number instead of 124, of course that is in range between 0 and 99999. Second number (the one that is changing) will always be integer !! (there won't be something like 123.45).
After division, I need to convert the result into integer (round it up or just ignore numbers after decimal point, which ever is faster).
Any ideas ? Thanks !
There are many ways to do this, with the easiest being a ROM. You don't need floating point anywhere since doing an integer divide and compensating for a non-zero remainder can give you the same results. I'd suggest calculating the first 600 results in MATLAB or a spreadsheet so you can see that handling values up to 99999 isn't necessary.
Also, some common nomenclature for range and precision is QI.F where I is the number of integer bits and F is the number of fractional bits. Thus 0..99999 would be Q17.0 and your output would be Q10.0.
There's an FP divide function in this VHDL file from this site.

Inverse of number in binary

Suppose we have some arbitrary positive number x.
Is there a method to represent its inverse in binary or x's inverse is 1/x - how does one express that in binary?
e.g. x=5 //101
x's inverse is 1/x, it's binary form is ...?
You'd find it the same way you would in decimal form: long division.
There is no shortcut just because you are in another base, although long division is significantly simpler.
Here is a very nice explanation of long division applied to binary numbers.
Although, just to let you know, most floating-point systems on today's machines do very fast division for you.
In general, the only practical way to "express in binary" an arbitrary fraction is as a pair of integers, numerator and denominator -- "floating point", the most commonly used (and hardware supported) binary representation of non-integer numbers, can represent exactly on those fractions whose denominator (when the fraction is reduced to the minimum terms) is a power of two (and, of course, only when the fixed number of bits allotted to the representation is sufficient for the number we'd like to represent -- but, the latter limitation will also hold for any fixed-size binary representation, including the simplest ones such as integers).
0.125 = 0.001b
0.0625 = 0.0001b
0.0078125 = 0.0000001b
0.00390625 = 0.00000001b
0.00048828125 = 0.00000000001b
0.000244140625 = 0.000000000001b
----------------------------------
0.199951171875 = 0.001100110011b
Knock yourself out if you want higher accuracy/precision.
Another form of multiplicative inverse takes advantage of the modulo nature of integer arithmetic as implemented on most computers; in your case the 32 bit value
11001100110011001100110011001101 (-858993459 signed int32 or 3435973837 unsigned int32) when multiplied by 5 equals 1 (mod 4294967296). Only values which are coprime with the power of two the modulo operates on have such multiplicative inverses.
If you just need the first few bits of a binary fraction number, this trick will give you those bits: (2 << 31) / x. But don't use this trick on any real software project. (because it is rough, inaccurate and plainly wrong way to represent the value)

Fast, Vectorizable method of taking floating point number modulus of special primes?

Is there a fast method for taking the modulus of a floating point number?
With integers, there are tricks for Mersenne primes, so that its possible to calculate y = x MOD 2^31-1 without needing division. integer trick
Can any similar tricks be applied for floating point numbers?
Preferably, in a way that can be converted into vector/SIMD operations, or moved into GPGPU code. This rules out using integer calculations on the floating point data.
The primes I'm interested in would be 2^7-1 and 2^31-1, although if there are more efficient ones for floating point numbers, those would be welcome.
One intended use of this algorithm would be to calculate a running "checksum" of input floating point numbers as they are being read into an algorithm. To avoid taking up too much of the calculation capability, I'd like to keep this lightweight.
Apparently a similar technique is used for larger numbers, particularly 2^127 - 1. Unfortunately, the math in the paper is beyond me, and I haven't been able to figure out how to convert it to smaller primes.
Example of floating point MOD 2^127 - 1 - HASH127
I looked at djb's paper, and you have it easier, since 31 bits fits comfortably into the 53-bit precision double significand. Assuming that your checksum consists of some ring operations over Z/(2**31 - 1), it will be easier (and faster) to solve the relaxed problem of computing a small representative of x mod Z/(2**31 - 1); at the end, you can use integer arithmetic to find a canonical one, which is slow but shouldn't happen too often.
The basic reduction step is to replace an integer x = y + 2**31 * z with y + z. The trick that djb uses is to compute w = (x + L) - L, where L is a large integer carefully chosen to provoke roundoff in such a way that z = 2**-31 * w. Then compute y = x - w and output y + z, which will have magnitude at most 2**32. (I apologize if this operation isn't quite enough; if so, please post your checksum algorithm.)
The choice of L involves knowing how precise the significand is. For the modulus 2**31 - 1, we want the unit of least precision (ulp) to be 2**31. For doubles in the range [1.0, 2.0), the ulp is 2**-52, so L should be 2**52 * 2**31. If you were doing this with the modulus 2**7 - 1, then you'd take L = 2**52 * 2**7. As djb notes, this trick depends crucially on intermediate results not being computed in higher precision.

Resources