Type conversion in VHDL: real to integer - Is the rounding mode specified?

Paebbels picture Paebbels · Jan 7, 2015 · Viewed 16.7k times · Source

While debugging the handling of user defined physical types in Vivado (read more), 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;
--use     IEEE.MATH_REAL.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 "16 - int_1 (natural(0.5)):  " & INTEGER'image(int_1) severity note;
  assert FALSE report "17 - int_2 (natural(-0.5)): " & INTEGER'image(int_2) severity note;

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

The dummy flip flop is used to prevent some tools from complaining about an empty design.

XST 14.7:

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

XST seems to use the mode round up and it handles the type conversion inclusive range check. So I must use integer(-0.5) instead of natural(-0.5).

Vivado 2014.4:

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

Synth seems to use the mode round to infinity and it handles the type conversion without range check. So maybe natural(..) is just an alias to integer(..).
The commented line: constant int_2 : INTEGER := natural(-0.5); throws no error.

GHDL 0.29:

GHDL 0.29 does no range check in natural(..). I know it's out dated, but since 0.31 hates me I can't tell if this is already fixed.

GHDL 0.31:

I'll present the results later. GHDL refuses to analyse my code because:
Top_PhysicalTest_Simple.vhdl:29:14: file std_logic_1164.v93 has changed and must be reanalysed

My questions:

  • Does VHDL define a rounding mode? And if so which one?
  • How should I handle rounding if no mode is defined?

Answer

Philippe Aubertin picture Philippe Aubertin · Jan 7, 2015

From IEEE Std 1076-2002 section 7.3.5 "Type conversions"

The conversion of a floating point value to an integer type rounds to
the nearest integer; if the value is halfway between two integers,
rounding may be up or down.

If you want something else, maybe functions in IEEE.MATH_REAL can be of some use (notably CEIL, FLOOR and/or TRUNC).