我目前正在编写一个测试来检查类型time
是否在各种FPGA供应商工具中正确合成/模拟。一个角落的情况是使用真正的文字作为时间值的抽象文字,例如:1.001 us
。
IEEE标准。 1076-2008,第5.2.4.1节或IEEE标准。 1076-1993,第3.1.3节,第8段规定:
存在与物理的每个值对应的位置编号 类型。与单位名称对应的值的位置编号是 由该单位名称表示的主要单位数。该 与物理文字对应的值的位置编号 抽象文字部分是不大的最大整数 比抽象文字的价值和位置的乘积 随附单位名称的编号。
根据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 ps
与1001 fs
进行比较以及将1.001 ns
与1001 ps
进行比较时,也会发生错误。同样C3
的手动计算是正确的,它应该不是真实的准确性问题。
请注意,Vivado的合成器报告了奇怪的结果:
Parameter C1 bound to: 32'b00111011101010100000110001000000 -- 1001000000
Parameter C2 bound to: 32'b10010011011101001011110001101010 -- 2473901162
Parameter C3 bound to: 32'sb00000000000000000000000000000001 -- 1
答案 0 :(得分:2)
这是浮点数的问题,并且几乎没有做VHDL。整数十进制数可以转换为二进制并返回小数而不会丢失信息(除非数字太大或太小)。小数分数不是这种情况。转换为二进制的十进制数1.001是不合理的。从二进制转换回十进制时,会出现舍入错误。
Quartus和ISE显示了预期的行为。
在Vivado案例中,foo_id
的MSB发生了一些事情。似乎在有符号和无符号整数之间发生了一些转换,它不应该有。并且C2
显然是圆润的。
您的示例可用于支持使用主要单元是最佳选择的规则。