在 VHDL 中,1.001 us 应该等于 1001 ns 吗?

Should be 1.001 us equal to 1001 ns in VHDL?

我目前正在编写一个测试来检查 time 类型是否在各种 FPGA 供应商工具中正确合成/模拟。一种特殊情况是使用真实文字作为时间值的抽象文字,例如:1.001 us.

IEEE 标准。 1076-2008,第 5.2.4.1 节或 IEEE 标准。 1076-1993,第 3.1.3 节,第 8 段指出:

There is a position number corresponding to each value of a physical type. The position number of the value corresponding to a unit name is the number of primary units represented by that unit name. The position number of the value corresponding to a physical literal with an abstract literal part is the largest integer that is not greater than the product of the value of the abstract literal and the position number of the accompanying unit name.

根据TIME的定义(见16.2或14.2节),主要单位是飞秒,所以1 us的位置数是1,000,000,000。因此,1.001 us的位置编号应该是1,001,000,000,这也是1001 ns的位置编号。因此,两个值应该相等。

但是,当我尝试合成或模拟以下精简单元时,我得到了不同的结果。我检查过,最小时间分辨率是 1 fs 或 1 ps.

entity physical_test is
    generic (
        C1 : time := 1001 ns;
        C2 : time := 1.001 us;
        C3 : time := TIME'val(integer(real(TIME'pos(1 us)) * 1.001))
    );
    port (
        y : out bit);
end entity physical_test;

architecture rtl of physical_test is
    function f return boolean is
    begin
        report "C1 = " & TIME'image(C1) severity note;
        report "C2 = " & TIME'image(C2) severity note;
        report "C3 = " & TIME'image(C3) severity note;
        return false;
    end f;

    constant C : boolean := f;
begin  -- architecture rtl
    y <= '0';
end architecture rtl;

QuestaSim (ModelSim) 是唯一报告预期结果的工具:

# ** Note: C1 = 1001000000 fs
# ** Note: C2 = 1001000000 fs
# ** Note: C3 = 1001000000 fs

但是,使用 Quartus 15.0 或 ISE 14.7 进行综合时的实际结果是:

Note: "C1 = 1001000000 fs"
Note: "C2 = 1000999999 fs"
Note: "C3 = 1001000000 fs"

因此,C2 的值不符合预期。如果我将引用的文本记为方程式,那么我将得到常量 C3 中的预期结果。 当我使用 ISE 14.7 或 Vivado 2015.4 的集成仿真器时,我得到类似的结果:

Note: "C1 = 1001000 ps"
Note: "C2 = 1000999 ps"
Note: "C3 = 1001000 ps"

那么,Quartus/ISE/Vivado 的行为应该被视为错误吗?还是VHDL标准允许1.001 us不等于1001 ns

编辑: 当我比较 1.001 ps1001 fs 以及比较 1.001 ns 和 [=28 时也会发生错误=].由于C3的人工计算是正确的,因此real的准确性应该没有问题。

请注意,Viv​​ado 的合成器报告了奇怪的结果:

Parameter C1 bound to: 32'b00111011101010100000110001000000    -- 1001000000
Parameter C2 bound to: 32'b10010011011101001011110001101010    -- 2473901162
Parameter C3 bound to: 32'sb00000000000000000000000000000001   -- 1

这是一个浮点数问题,与 VHDL 关系不大。整数十进制数可以转换为二进制数,然后再转换回十进制数,而不会丢失信息(除非数字太大或太小)。小数不是这种情况。十进制数 1.001 转换为二进制是无理数。从二进制转换回十进制时,会出现舍入误差。

Quartus 和 ISE 表现出预期的行为。

在 Vivado 案例中,C2 的 MSB 发生了一些变化。似乎有符号和无符号整数之间发生了一些本不应该发生的转换。 C3 显然是四舍五入的。

您的示例可用于支持使用主要单位是最佳选择的规则。