cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Explorer
Explorer
10,997 Views
Registered: ‎04-24-2014

Type conversion in VHDL: real to integer - Different behavior in Vivado Synth

While debugging the handling of user defined physical types in Vivado (I'll write a seperate post for this issue), I found a different behavior for type conversions from real to integer.

 

Here is my example code:

 

library IEEE;
use     IEEE.STD_LOGIC_1164.ALL;

entity Top_PhysicalTest_Simple is
  port (
    Clock : in STD_LOGIC;
    Input : in STD_LOGIC;
    Output : out STD_LOGIC
  );
end;

architecture top of Top_PhysicalTest_Simple is
  constant int_1     : INTEGER  := natural(0.5);
  constant int_2     : INTEGER  := integer(-0.5);
--  constant int_2     : INTEGER  := natural(-0.5);
begin
  assert FALSE report "int_1 (natural(0.5)):  " & INTEGER'image(int_1) severity note;
  assert FALSE report "int_2 (integer(-0.5)): " & INTEGER'image(int_2) severity note;
--  assert FALSE report "int_2 (natural(-0.5)): " & INTEGER'image(int_2) severity note;

  Output <= Input when rising_edge(Clock);
end;

 

XST 14.7 prints these lines in the synthesis report:

Elaborating entity <Top_PhysicalTest_Simple> (architecture <top>) from library <work>.
Note: "int_1 (natural(0.5)):  1"
Note: "int_2 (integer(-0.5)): 0"

 

Vivado 2014.4 Synth reports these messages:

[Synth 8-63] RTL assertion: "int_1 (natural(0.5)):  1" ["D:/.../Top_PhysicalTest_Simple.vhdl":80]
[Synth 8-63] RTL assertion: "int_2 (natural(-0.5)): -1" ["D:/.../Top_PhysicalTest_Simple.vhdl":81]

 

As you can see XST rounds -0.5 to 0 and Synth rounds it to -1 (round down / round from zero?)

Moreover Synth does not perform a range check while converting a negative real value with natural(...). XST requires integer(...) for proper conversion.

 

So, can anyone explain why:

  • Synth has a different behavior in type conversion?
  • Synth does not propperly check ranges in natural(...)?

Some assumptions:

  • type conversion / rounding is done as follows:
        return sign(x) * integer(abs(x));
  • natural(...) is just an alias of integer(...)

 

0 Kudos