Fixed and Floating point VHDL FAQ
What follows are frequently asked questions about the fixed and floating point VHDL packages. VHDL-93 source code can be found on the VHDL-2008 support library page. You will find these packages built into several implimentations of VHDL.
Under the hood, all of the fixed and floating point functions call functions from the "numeric_std" package. Much work was done to make sure that these algorithms would be as fast as possible. You can expect a fixed point multiply to be just as fast as an UNSIGNED multiply. Floating point gives you about 3X overhead. However you get much more accurate results. My best results have been gotten by mixing the two.
You don't need them. Use the "scalb" function. This function works as follows:
variable uf1 : ufixed (5 downto 0); variable uf2 : ufixed (4 downto -1); ... uf2 := scalb (uf1, -1); -- shift right by 1The nice thing about this function is that you don't loose any data. Note that under the hood, for some synthesis tools, this function is implimented with shift operators. Standard shift operators are built into VHDL-2008, but some vendors have not implemented them.
The problem here is that the vector returned will be "ufixed (integer'low to integer'low+Y'high)" or essentially 2**-32,000 (a VERY small number). Instead, use the resize function:
X <= resize (Y, X'high, X'low);The resize function is used to all of the rouding in the fixed point package.
The sizing was done so that you never need to round, thus removing one addition stage, and making the results run faster. For the applications where this is just a pain, I've created fixed_noresize.vhdl. This package creates the types "fixedu" and "fixeds" (which are similar to "ufixed" and "sfixed"). However these new types have the same sizing rules as numeric_std UNSIGNED and SIGNED.
Note that there is also an "add_carry" procedure in the fixed point package for fixed point accumulators, which can be used like this:
variable uf3: ufixed (3 downto -2); constant one : ufixed (0 downto 0) := "1"; ... add_carry ( L => uf3, R => one, result => uf3, c_in => '0', c_out => open);This procedure will return a result which is the "widest" of the inputs. Overflow will show up in the "c_out" output.
Yes, it will be, a floating point divider is lots of logic. You will need to pipeline these functions. Some synthsis tools will do this for you automatically. Others will make you pipline them manually. I have already created pipelined versions of many of them.
There is a function "to_sfixed(ufixed)" which increases the size of the output by 1 (the sign bit). The "to_ufixed(sfixed)" function returns a vector of the same size as the input.
So far:
Need some help with this code?
Drop me an e-mail, maybe I can help.
My company will also allow me to consult for you.
This web page is brought to you by the EDA Industry Working Groups and Accellera.