# Thread: Math calculations in VHDL

1. Altera Teacher
Join Date
Feb 2011
Posts
60
Rep Power
1

## Math calculations in VHDL

Hi all,
I need a little help with my design, there are a few issues that I'm trying to resolve.
My design flow is as following: A signal is sampled by a 16bit A2D, multiplied by 2 another 16bit signals (which results in 2 32bit signals). After a few manipulations I need to implement a formula that uses those 2 signals with division, multiplication and a few other functions that are calculated using LUTs. The LUTs are designed for a signal normalized to the range of 0 - pi/2. Note that after the formula the signals will be converted to 32bit floating-point signals.
The formula requires some fractional calculations so I'm trying to use the fixed point package by David Bishop but I'm facing a few issues:
1. How am I supposed to convert the 32bit signals (integer) to 32 fixed point numbers?
2. I'm trying to divide the 2 32bit signals - what is the best way to do this? I tried the lpm_divide megafunction but I get a quotient and a remain while I need the whole number (i.e. 5.65 and not only 5).
3. How exactly am I supposed to use the fixed-point package? I have the following libraries, is that enough?
Library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.fixed_float_types.all;
use ieee.fixed_pkg.all;

Thanks in advance, help will be very appreciated.

2. Altera Scholar
Join Date
Jan 2012
Posts
31
Rep Power
1

## Re: Math calculations in VHDL

Fixed point unlike the floating point arithmetics does not need any package at all. Every math operation implemented for integers is applicable to fixed point numbers.
As for the division this might be implemented using CORDIC algorithms.

3. Altera Teacher
Join Date
Feb 2011
Posts
60
Rep Power
1

## Re: Math calculations in VHDL

I'm sorry if I wasn't clear enough, I understand the theory, my problem is with the implementation.
First of all, how can I get the whole number from the lpm_divide function (including the fractional part).
Second how can I scale the 32bit integers from the first part of my design so that they can be used as 32bit fixed-point fractions in the second part.

4. Moderator **Forum Master**
Join Date
Oct 2008
Posts
3,276
Rep Power
1

## Re: Math calculations in VHDL

well, if its an integer, it has no fractional part to it. An integer is just a fixed point number with no fractional part. Unless you are talking about an integer you really meant was a fractional number and you biassed it by 2^n (where N is the number of fractional bits). In which case you need to tell us what the value of N is. You DONT need an LPM divide for this.

1. You zero pad the inputs to the correct number of bits (integer and fractional) and the result will be correct.

2. You need to just assign it to the correct sized ufixed or sfixed values (fixed point is just integers, offset by 2^n)

either way, there are the to_ufixed and to_sfixed functions from the fixed point package.

one point to note. You should not be using the std_logic_unsigned package, its not an IEEE standard. If you have a number, you shouldnt make it a std_logic_vector. There is no need to make ports std_logic_vector, they can be anything.

5. Altera Teacher
Join Date
Feb 2011
Posts
60
Rep Power
1

## Re: Math calculations in VHDL

The reason I said that there are fractions is because when I divide the 2 32bit integers I will probably get a fraction.
You mean that I should convert the 32bit integers to ufixed and then divide them and store the answer in a 64bit ufixed signal? I tried to do that but I got a strange error regarding the "/" operator, that's why I used the lpm_divide megafunction instead, which works for std_logic_vector.
If I'm not using the std_logic_unsigned package I get an error even for a "+" sign, where am I wrong? Have I included all the correct files from the fixed-point package?

6. Moderator **Forum Master**
Join Date
Oct 2008
Posts
3,276
Rep Power
1

## Re: Math calculations in VHDL

Yes, you will get a fraction. But if they start out as 32 bit, you will need a lot more bits to store the result. But making it a 32.32 sfixed is rather easy (remember integers are signed. For unsigned, you can only have a max of 31 bit integers). Do you really mean integers as in the VHDL type integer, or just a number that arrives via a 32 bit bus?

signal my_number : sfixed(31 downto -32);
my_number <= to_sfixed(input, 31, -32);

And this is free in terms of synthesis because you're really just appending a load of zeros to it. Then you can convert this to a std_logic_vector (with the to_slv function) so you can connect it into the lpm divide. No, you should not use the "/" function unless you can get away with a pipeline length of 1 (until altera sort out their register placement inside infered dividers properly!)

you shouldnt do + with std_logic_vectors, you should keep them in ufixed or sfixed type when you do this.

I think at this point you need to post some code to show us what you're actually trying to do.

7. Altera Teacher
Join Date
Feb 2011
Posts
60
Rep Power
1

## Re: Math calculations in VHDL

Below is a simple code that uses the lpm_divide megafunction to divide 2 32bit numbers. I tried to implement your comments from the previous post. The numbers are 32bit std_logic_vectors (I refered to them as integers i.e. a number that arrives via a 32bit bus). I want to get the full result (including the fractional part) because the next step will be performing modulus pi/2 on the result. I'm getting the following compilation error: Error (10344): VHDL expression error at PreNICOMFunction_fixed.vhd(: expression has 0 elements, but must have 64 elements (it refers to the line I_fp <= to_ufixed(I,31,-32)
1. What am I doing wrong?
2. How can I convert the divider result to a fractional number?

Library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.fixed_float_types.all;
use ieee.fixed_pkg.all;

entity PreNICOMFunction_fixed is
port (
clock : in std_logic;
reset : in std_logic;
I : in std_logic_vector (31 downto 0);
Q : in std_logic_vector (31 downto 0);
V0 : in std_logic_vector (31 downto 0) --;
-- temp_res : out ufixed (31 downto -32)
);
end PreNICOMFunction_fixed;

architecture rtl of PreNICOMFunction_fixed is

component lpm_divider1 IS --32 clocks latency
PORT (
aclr : IN STD_LOGIC ;
clock : IN STD_LOGIC ;
denom : IN STD_LOGIC_VECTOR (63 DOWNTO 0);
numer : IN STD_LOGIC_VECTOR (63 DOWNTO 0);
quotient : OUT STD_LOGIC_VECTOR (63 DOWNTO 0);
remain : OUT STD_LOGIC_VECTOR (63 DOWNTO 0)
);
END component lpm_divider1;

type fsm_type1 is (s0, s1, s2, s3, s4);
signal fsm1 : fsm_type1 := s0;
signal QdivI : std_logic_vector (63 downto 0) := (others => '0');
signal QdivI_remain : std_logic_vector (63 downto 0) := (others => '0');

signal I_ff : std_logic_vector (31 downto 0) := (others => '0');
signal Q_ff : std_logic_vector (31 downto 0) := (others => '0');
signal I_fp : ufixed (31 downto -32) := (others => '0');
signal Q_fp : ufixed (31 downto -32) := (others => '0');
signal div_res : ufixed (31 downto -32) := (others => '0');
signal cntr1 : ufixed (4 downto 0) := (others => '0');
constant div_latency : ufixed (4 downto 0) := "11111";

begin

divider : component lpm_divider1
port map (
aclr => '0',
clock => clock,
denom => to_slv(I_fp),
numer => to_slv(Q_fp),
quotient => QdivI,
remain => QdivI_remain
);

main : process (clock)
begin
if (rising_edge(clock)) then
I_ff <= I;
Q_ff <= Q;
case fsm1 is
when s0 => if ((I_ff /= I) or (Q_ff /= Q)) then --New data availabe
I_fp <= to_ufixed(I,31,-32);
Q_fp <= to_ufixed(Q,31,-32);
fsm1 <= s1;
end if;
-- atanLUT_clk <= '0';

when s1 => if (cntr1 < div_latency) then --Wait for the division operation to complete (Q/I)
cntr1 <= cntr1 + 1;
else
cntr1 <= (others => '0');
fsm1 <= s0;
end if;

when others => fsm1 <= s0;

end case;
end if;
end process main;
end rtl;

8. Altera Teacher
Join Date
Feb 2011
Posts
60
Rep Power
1

## Re: Math calculations in VHDL

I modified the code so it compiles now but I still get a quotient and a remain and not the whole result. Besides, if my input is std_logic_vector why convert it to ufixed and then back to std_logic_vector?

Library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.fixed_float_types.all;
use ieee.fixed_pkg.all;

entity PreNICOMFunction_fixed is
port (
clock : in std_logic;
reset : in std_logic;
I : in std_logic_vector (31 downto 0);
Q : in std_logic_vector (31 downto 0);
V0 : in std_logic_vector (31 downto 0) --;
-- temp_res : out ufixed (31 downto -32)
);
end PreNICOMFunction_fixed;

architecture rtl of PreNICOMFunction_fixed is

component lpm_divider1 IS --32 clocks latency
PORT (
aclr : IN STD_LOGIC ;
clock : IN STD_LOGIC ;
denom : IN STD_LOGIC_VECTOR (63 DOWNTO 0);
numer : IN STD_LOGIC_VECTOR (63 DOWNTO 0);
quotient : OUT STD_LOGIC_VECTOR (63 DOWNTO 0);
remain : OUT STD_LOGIC_VECTOR (63 DOWNTO 0)
);
END component lpm_divider1;

type fsm_type1 is (s0, s1, s2, s3, s4);
signal fsm1 : fsm_type1 := s0;
signal QdivI : std_logic_vector (63 downto 0) := (others => '0');
signal QdivI_remain : std_logic_vector (63 downto 0) := (others => '0');

signal I_ff : std_logic_vector (31 downto 0) := (others => '0');
signal Q_ff : std_logic_vector (31 downto 0) := (others => '0');
signal I_fp : ufixed (31 downto -32) := (others => '0');
signal Q_fp : ufixed (31 downto -32) := (others => '0');
signal div_res : ufixed (31 downto -32) := (others => '0');
signal cntr1 : ufixed (4 downto 0) := (others => '0');
constant div_latency : ufixed (4 downto 0) := "11111";

begin

divider : component lpm_divider1
port map (
aclr => '0',
clock => clock,
denom => to_slv(I_fp),
numer => to_slv(Q_fp),
quotient => QdivI,
remain => QdivI_remain
);

main : process (clock)
begin
if (rising_edge(clock)) then
I_ff <= I;
Q_ff <= Q;
case fsm1 is
when s0 => if ((I_ff /= I) or (Q_ff /= Q)) then --New data availabe
I_fp <= to_ufixed(unsigned(I),31,-32);
Q_fp <= to_ufixed(unsigned(Q),31,-32);
fsm1 <= s1;
end if;

when s1 => if (cntr1 < div_latency) then --Wait for the division operation to complete (Q/I)
cntr1 <= resize(cntr1 + 1, cntr1'high, cntr1'low);
else
cntr1 <= (others => '0');
fsm1 <= s0;
end if;

when others => fsm1 <= s0;

end case;

end if;
end process main;
end rtl;

9. Moderator **Forum Master**
Join Date
Oct 2008
Posts
3,276
Rep Power
1

## Re: Math calculations in VHDL

You will always get a remainder because you would otherwise need more bits to get and even smaller result in the quotient, which is not possible with lpm divide (64 bits being the max).

You dont really need to use sfixed, but you still need to append all the '0's onto the end when connecting it to the lpm_divide.

And I notice you dont have any outputs from this block - are you going to add them later?

10. Altera Teacher
Join Date
Feb 2011
Posts
60
Rep Power
1

## Re: Math calculations in VHDL

Yes, the block is going to be more complicated. After the division I need to perform modulus pi/2 on the result and then use it with an LUT which is based on fractional numbers, that's why I need the fractional result. How can I find it?

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•