# Thread: VHDL Math Real & Quartus

1. Altera Teacher
Join Date
May 2006
Location
Mountain View, CA
Posts
128
Rep Power
1

## VHDL Math Real & Quartus

I've been using the VHDL package ieee.math_real to declare parameters, the idea being to condense as much information in a design file as possible. in particular, for fixed point operations in feedback controls systems, it helps to see the scaling of the parameters directly in the design file. For example, the code below does synthesize correctly in Quartus:

Code:
`constant RecipSqrt3  :   signed(N-1 downto 0) := to_signed(integer(real(ROUND((2.0**15)*(0.577350269189626)))),16);`
However, the code below does not:

Code:
`variable RecipFactor :   real := ROUND((2.0**15)*(1.0/(SQRT(3.0))));`
Quartus gives a message about this; upon further checking the / operator is not defined for A/B where both A and B are real. It is defined, however, for the complex numbers in the complex package of math_real.

I like the notation of 1.0/SQRT(3.0) better than 0.577350269189626 for example.

Has anyone had success with the / operator for complex numbers or real numbers? Thanks in advance. James

2. Altera Guru
Join Date
Jun 2007
Location
B-Hoegaarden
Posts
737
Rep Power
1

## Re: VHDL Math Real & Quartus

I remember having that divide problem once also, but I forgot when ... I don't divide many 'real's though, but recently I did this:
Code:
`ARCZ => integer( ( real(PI_TIMES_TWO) * ARCTAN( 2.0 ** (-(i))) / MATH_2_PI)) ,`
This is in Quartus II 11.1sp1.

Code:
`	variable RecipFactor :   real := ROUND((2.0**15)*(1.0/(SQRT(3.0))));`
and got no other warning than:
Warning (10542): VHDL Variable Declaration warning at math_real.vhd(2373): used initial value expression for variable "RECIPROCAL" because variable was never assigned a value
but that is a long time annoyance ...
Last edited by josyb; June 5th, 2012 at 03:56 AM.

3. FvM
Altera Guru
Join Date
Dec 2007
Location
Bochum Germany
Posts
5,785
Rep Power
1

## Re: VHDL Math Real & Quartus

I don't understand what you are trying to achieve. A "variable" to be used for compile time calculations can be defined as a constant.

4. Altera Teacher
Join Date
May 2006
Location
Mountain View, CA
Posts
128
Rep Power
1

## Re: VHDL Math Real & Quartus

What I am / was trying to achieve is completely parameterized code; with no errors or warning messages . . . James

5. Altera Guru
Join Date
Aug 2005
Location
California
Posts
3,678
Rep Power
1

## Re: VHDL Math Real & Quartus

What I am / was trying to achieve is completely parameterized code; with no errors or warning messages . . . James
Right, that was what FVM was getting at. You can clear that particular error by using 'constant RecipFactor' instead of 'variable RecipFactor'.

Cheers,
Dave

6. Altera Guru
Join Date
Jun 2007
Location
B-Hoegaarden
Posts
737
Rep Power
1

## Re: VHDL Math Real & Quartus

Originally Posted by dwh@ovro.caltech.edu
Right, that was what FVM was getting at. You can clear that particular error by using 'constant RecipFactor' instead of 'variable RecipFactor'.

Cheers,
Dave
James' question was why he got an error for the 'variable' construct not whether his code was any good. He specifically wanted to show the '1/sqrt(3)' in his equation instead of an obscure 0.577350269, which is a sound idea. There are workarounds where he wouldn't have to use a division ( pow(sqrt(3.0), -1.0) , but again that would be not pure ...
Of course Frank's remark stays valid.
But judging by his silence James has found what he was looking for?
Last edited by josyb; June 5th, 2012 at 01:00 PM.

7. Altera Teacher
Join Date
May 2006
Location
Mountain View, CA
Posts
128
Rep Power
1

## Re: VHDL Math Real & Quartus

Thanks for the feedback everyone . . . However, the RecipFactor if made a constant still gives a message, when synthesizing the VHDL module shown below:

Warning (10542): VHDL Variable Declaration warning at math_real.vhd(2373): used initial value expression for variable "RECIPROCAL" because variable was never assigned a value

As mentioned, this is what I was trying to avoid. In the code below, the constant RecipSqrt3 is clean; no messages are reported by Quartus at compile time.

Best,

James

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;

entity IFBscale is
port(
MCLK : in std_logic;
HRST : in std_logic;
START : in std_logic;

IA : in std_logic_vector(15 downto 0);
IB : in std_logic_vector(15 downto 0);

ALPHA : out std_logic_vector(15 downto 0);
BETA : out std_logic_vector(15 downto 0);

ScaleFactor : in std_logic_vector(15 downto 0);

DONE : out std_logic

);
end IFBscale;

architecture RTL of IFBscale is

constant N : integer := 16;
constant N2 : integer := 32;
signal factor : real;
constant RecipFactor : real := ROUND((2.0**15)*(1.0/SQRT(3.0)));
constant RecipSqrt3 : std_logic_vector(N-1 downto 0) := std_logic_vector(to_signed(integer(real(ROUND((2.0 **15)*(0.577350269189626)))),16));

signal betax : std_logic_vector(2*N-1 downto 0);

type baseDataType is record
x : signed(N-1 downto 0);
done : std_logic;
slv : std_logic_vector(N*2-1 downto 0);
slvN : std_logic_vector(N-1 downto 0);
end record;

signal ias,ibs,sum : baseDataType;

signal donex : std_logic;
signal betay : signed(N-1 downto 0);

begin

/*----------------------------
Register Outputs
----------------------------*/
oReg: process(all) begin
if HRST then
ALPHA <= (others => '0');
BETA <= (others => '0');
DONE <= '0';
elsif rising_edge(MCLK) then
ALPHA <= std_logic_vector(ias.x);
if donex then
BETA <= std_logic_vector(betax(N2-2 downto N-1));
DONE <= '1';
else
DONE <= '0';
end if;
end if;
end process oReg;

/*----------------------------
Scale IA
----------------------------*/
Umult1 : entity work.signed_mult2(rtl)
generic map(arg_size => N)
port map(
CLK => MCLK,
HRST => HRST,
START => START,
DONE => ias.done,
a => IA,
b => ScaleFactor,
result => ias.slv
);
/*----------------------------
Scale IB
----------------------------*/
Umult2: entity work.signed_mult2(rtl)
generic map(arg_size => N)
port map(
CLK => MCLK,
HRST => HRST,
START => START,
a => IB,
b => ScaleFactor,
result => ibs.slv
);

ias.x <= signed(ias.slv(N2-3 downto N-2));
ibs.x <= signed(ibs.slv(N2-3 downto N-2));

process(all) begin
if HRST then
sum.x <= (others => '0');
sum.done <= '0';
elsif rising_edge(MCLK) then
if ias.done then
sum.x <= X"0000" - ias.x - shift_left(ibs.x,1);
sum.done <= '1';
else
sum.done <= '0';
end if;
end if;
end process;

sum.slvN <= std_logic_vector(sum.x);
/*----------------------------
Scale Ibeta by1/sqrt(3)
----------------------------*/
Umult3: entity work.signed_mult2(rtl)
generic map(arg_size => N)
port map(
CLK => MCLK,
HRST => HRST,
START => sum.done,
DONE => donex,
a => sum.slvN,
b => RecipSqrt3,
result => betax
);

end RTL;

8. Altera Teacher
Join Date
May 2006
Location
Mountain View, CA
Posts
128
Rep Power
1

## Re: VHDL Math Real & Quartus

This issue with ieee.math_real makes me what to add the guidelines for declaring constants as part of my internal VHDL style guide; suited for synthesis with Quartus. I've haven't seen this type of detailed exposition in books, references, etc. James

9. Altera Guru
Join Date
Aug 2005
Location
California
Posts
3,678
Rep Power
1

## Re: VHDL Math Real & Quartus

Warning (10542): VHDL Variable Declaration warning at math_real.vhd(2373): used initial value expression for variable "RECIPROCAL" because variable was never assigned a value
The reason for the warning is lines like this in math_real-body.vhdl (downloadable from the IEEE web site):

variable RECIPROCAL: BOOLEAN := X < 0.0;-- Check sign of argument
This should be 'constant'.

Given that this is in the IEEE library code, I don't think you can really do much about it. You might be able to recompile the IEEE libraries to over-ride whatever Quartus uses internally.

Cheers,
Dave

10. FvM
Altera Guru
Join Date
Dec 2007
Location
Bochum Germany
Posts
5,785
Rep Power
1

## Re: VHDL Math Real & Quartus

Thanks for clarifying the problem with IEEE library code. I was in fact assuming that the variable declaration in your code causes the warning.

The problem is sligthly different and hasn't to do with constant versus variable. It's quite normal, that variables inside library functions are involved when calculating constants. The warning is due to the fact, that the initial value expression in variable declaration isn't understood by Quartus as an actual assignment. You may consider this as a minor Quartus bug.

P.S.: The message directive -- altera meassage_off xxxxx isn't supported for packages, so the issue has to be resolved by Altera.
Last edited by FvM; June 5th, 2012 at 10:29 PM.

#### Posting Permissions

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