Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

VHDL Numeric Type Conversion

I am using a bunch of variables to do some math. These variables, X and Y coordinates, are converted to different numeric types for ease of math operations. The outputs, Xm and Ym, are SLV's and depend on the intermediary variables Xc and Yc. Xm and Ym are simulated correctly using Quartus II 9.1 native simulator, but the intermediary variables Xp and Yp, who also depend on Xc and Yc, are not. How could this be? Here are the relevant snipets of my code:

---

use ieee.numeric_std.all;

...

generic(dst_max : positive := 300000);

...

Xm, Ym : out std_logic_vector(19 downto 0);

...

variable d1, d2, d3, d4 : natural range 0 to dst_max;

variable Xc, Yc, Xc1, Yc1, Xp, Yp : integer range -dst_max to dst_max;

variable Xc_sv, Yc_sv, Xc_sv1, Yc_sv1 : signed(19 downto 0);

...

elsif (d2 /= 0) and (d4 /= 0) then

Xc1 := (d4 - d2);

Xc_sv1 := to_signed(Xc1, 20);

Xc_sv := Xc_sv1(19) & Xc_sv1(19 downto 1); -- shift right by 1 to divide by 2

Xc := to_integer(Xc_sv);

else

Xc := Xp; -- use previous

end if;

...

elsif (d1 /= 0) and (d3 /= 0) then

Yc1 := (d3 - d1);

Yc_sv1 := to_signed(Yc1, 20);

Yc_sv := Yc_sv1(19) & Yc_sv1(19 downto 1); -- shift right by 1 to divide by 2

Yc := to_integer(Yc_sv);

else

Yc := Yp;

end if;

Xp := Xc; -- update previous

Yp := Yc; -- Xp and Yp DO NOT SIMULATE CORRECTLY

Xm <= std_logic_vector(to_signed(-Xc, 20)); -- move

Ym <= std_logic_vector(to_signed(-Yc, 20)); -- Xm and Ym SIMULATE CORRECTLY

---

Simulation Results:

d1 = 1955, d2 = 300000, d3 = 158100, d4 = 23456

Xp should be -138272, but is 430016

Yp should be 78072, but is -369448

Xm is 138272 (correct)

Ym is -78072 (correct)

Xc* and Yc* could not be displayed by the simulator

12 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    the fact you are doing post synthesis simulation probably explains why they are not working. Quartus is probably converting everything to a signed number during synthesis, or you are showing them in the simulator as signed when actually they are unsigned.

    --- Quote Start ---

    I do know the difference b/t variables and signals. I wanted to use variables because they don't represent HW and I don't have to wait for the clock to change them.

    --- Quote End ---

    This shows you clearly do not understand variables. Just because they are updated immediatly does not mean they do not represent hardware. At the very least, variables may represent a wire between one register to the next. And in some circumstances they can be used to instantiate anything a signal can.

    Consider the following two bits of code. The first one has a single register between the input and output.

    
    process(clk)
      variable v : std_logic;
    begin
      if rising_edge(clk) then
        v := input;
        output <= v;
      end if;
    end process;
    

    Now this code:

    
    process(clk)
      variable v : std_logic;
    begin
      if rising_edge(clk) then
        output <= v;
        v := input;
      end if;
    end process;
    

    Now v represents an additional register in the pipeline, so there are 2 registers between the input and output instead of just 1.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The problem with variables is, that they can represent hardware, as Tricky has shown, but they can be also purely virtual, removed during synthesis. This won't be a problem normally, but if arithmetic overflows and implicite type conversions "happen" to the data, the result may be difficult to predict.

    --- Quote Start ---

    I already stated that I changed all my variables to type integer. So the only type conversion I am doing is for the outputs Xm and Ym.

    --- Quote End ---

    As already mentioned, I see a possible overflow and an implicite type conversion in Xc1 := (d4 - d2). The input is unsigned integer and the output signed integer. As previously discussed, there's a possible ambiguousity, because the integer subtypes are synthesized as signed and unsigned by the compiler. So the synthesized result may be different from expectable integer behaviour or ModelSim simulation.

    What to do? You can either complain about possible incorrect synthesis of integer subtypes by Quartus, or try to avoid these ambiguousities by a clearer typing.