VHDL 中有两个
time
值,例如:
constant t_1 : time := 1 us;
constant t_2 : time := 300 ms;
如何计算以
time
类型表示的两个 real
值之间的比率?
用“:”表示的比率应例如给出:
t_1 : t_2 = 3.333333e-006
t_2 : t_1 = 3.000000e+005
面临的挑战是,两种物理类型的 VHDL 除法(如执行
t_1 / t_2
)返回一个(通用)整数,因此 t_1 / t_2
的结果为 0,而不是 0.0 和 1.0 之间的所需值。
该解决方案应该是普遍适用的,并且也适用于最短时间超过
1 fs
的模拟器。
Modelsim 有一个
modelsim_lib.util
包,其中包含 to_real()
函数,Aldec 在 aldec.aldec_tools
中有相同的功能。
如果您需要一个可用于综合生成常量的便携式解决方案,我有一个 timing_ops 包,其中包含
to_real()
函数以及许多其他与时间相关的实用程序。 to_real()
函数会进行到整数的中间转换,但会通过预缩放来智能地处理超出典型 32 位整数范围的大值 64 位时间。如果可用,则支持 64 位整数。转换函数通过使用 VHDL-2008 resolution_limit
函数的修改版本来了解当前时间分辨率。当模拟器分辨率尽可能大时,您将获得最佳的整数转换精度。在 1fs 分辨率下,您可能会失去一些大时间值的准确性。当进行时间 -> 实际 -> 时间的往返转换时,它将保留 IEEE 64 位浮点尾数中可用的最大 53 位。
这个包有两个版本。主要的定义了频率的物理类型,可以在 Quartus 和 Vivado(以及任何模拟器)中工作,但不能在 XST 中工作。精简的 timing_ops_xilinx 删除了物理类型以支持 XST。逻辑包名称仍然保留
timing_ops
,因此您的代码仍然可以移植,只需在库映射中进行更改即可。
我也尝试进行此类计算,但在某些供应商工具上失败了......我当前的解决方案是使用实常数来表示以 ns 为单位的计时或以 MHz 为单位的频率。如果我需要具体的时间,我将实常数乘以 1 ns,得到一个时间。
-- specify timing in microseconds
constant myTiming_us : real := 100.0;
-- scale timing and convert it to a time
constant myTime : time := 1 ns * myTiming_us * 1000.0;
耶!我发现我的旧错误/错误注释为什么我不直接使用时间类型......
以下所有注释均于 2011 年使用 Xilinx XST O.61xd 版本进行了测试 - 如果我没记错的话,这是 ISE 13.2。
这是我的笔记:
-- type TIME is not supported in Xilinx Synthese Tools (XST) - Version O.61xd 2011
-- declaration of constants with type TIME => ERROR
-- usage of type TIME in functions => ERROR
function kHz2Time(Freq_kHz : POSITIVE) return TIME is
begin
return 1.0 ms / real(Freq_kHz);
end;
-- has no static result in Xilinx Synthese Tools (XST) - Version O.61xd 2011
function kHz2Time(Freq_kHz : REAL) return TIME is
begin
return 1.0 ms / Freq_kHz;
end;
-- has no static result in Xilinx Synthese Tools (XST) - Version O.61xd 2011
function kHz2Time(Freq_kHz : REAL) return TIME is
constant result : TIME := 1.0 ms / Freq_kHz;
begin
return result;
end;
所有 3 个变体均已注释(此处未注释以使用语法突出显示),并且在 XST 13.2 中不起作用。如果我没记错的话,iSim 13.2 这段代码没有问题。
我再次在 ISE 14.7 下运行测试,到目前为止它似乎工作正常。 这样“没有静态结果”的问题就解决了。 TIME 类型的常量也可以用于综合。
此外,还可以定义新的物理时间:
-- not yet supported by Xilinx Synthese Tools (XST) - Version 13.2 (O.61xd 2011)
type FREQ is range 0 to INTEGER'high units
Hz;
kHz = 1000 Hz;
MHz = 1000 kHz;
GHz = 1000 MHz;
end units;
频率到时间的转换有点棘手:
function to_time(Frequency : FREQ) return TIME is
variable Result : TIME;
begin
assert MY_VERBOSE report "to_time: Frequency = " & FREQ'image(Frequency) severity note;
if (Frequency < 1.0 kHz) then
Result := (1.0 / real(Frequency / 1.0 Hz)) * 1.0 sec;
elsif (Frequency < 1.0 MHz) then
Result := (1.0 / real(Frequency / 1.0 kHz)) * 1.0 ms;
elsif (Frequency < 1.0 GHz) then
Result := (1.0 / real(Frequency / 1.0 MHz)) * 1.0 us;
else
Result := (1.0 / real(Frequency / 1.0 GHz)) * 1.0 ns;
end if;
assert MY_VERBOSE report " return " & TIME'image(Result) severity note;
return Result;
end function;
XST 14.7 和 iSim 14.7 不再抱怨此代码。