- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
constant RecipSqrt3 : signed(N-1 downto 0) := to_signed(integer(real(ROUND((2.0**15)*(0.577350269189626)))),16);
However, the code below does not: 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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
ARCZ => integer( ( real(PI_TIMES_TWO) * ARCTAN( 2.0 ** (-(i))) / MATH_2_PI)) ,
This is in Quartus II 11.1sp1. I tried your code variable RecipFactor : real := ROUND((2.0**15)*(1.0/(SQRT(3.0))));
and got no other warning than: --- Quote Start --- 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 --- Quote End --- but that is a long time annoyance ...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What I am / was trying to achieve is completely parameterized code; with no errors or warning messages . . . James
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- What I am / was trying to achieve is completely parameterized code; with no errors or warning messages . . . James --- Quote End --- Right, that was what FVM was getting at. You can clear that particular error by using 'constant RecipFactor' instead of 'variable RecipFactor'. Cheers, Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Right, that was what FVM was getting at. You can clear that particular error by using 'constant RecipFactor' instead of 'variable RecipFactor'. Cheers, Dave --- Quote End --- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 --- Quote Start --- 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; --- Quote End ---- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- 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 --- Quote End --- The reason for the warning is lines like this in math_real-body.vhdl (downloadable from the IEEE web site): --- Quote Start --- variable RECIPROCAL: BOOLEAN := X < 0.0;-- Check sign of argument --- Quote End --- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FvM & Dave,
Thanks for the feedback, and I would agree that this is a minor Quartus bug. My main approach will be to not use reciprocal factors when declaring these types of constants. Best, James- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The same warning is caused by a number of other frequently used ieee.math_real, e.g. trigonometric functions.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page