在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和0.0之间的所需值。 1.0。
该解决方案通常适用,也适用于最短时间超过1 fs
的模拟器。
答案 0 :(得分:2)
Modelsim有一个modelsim_lib.util
包,其中包含to_real()
个函数,Aldec在aldec.aldec_tools
中也有相同的内容。
如果你需要一个可以在综合中用于生成常量的可移植解决方案,我有timing_ops package包含to_real()
函数以及许多其他时间相关的实用程序。 to_real()
函数进行中间转换为整数,但通过预先缩放它,智能地处理超过典型32位整数范围的64位时间的大值。如果可用,则支持64位整数。转换函数通过使用VHDL-2008 resolution_limit
函数的修改版本来了解当前时间分辨率。当模拟器分辨率尽可能大时,您将获得整数转换的最佳精度。在1fs分辨率下,您可能会在大时间值上失去一些准确性。当从时间进行往返转换时,它将保留IEEE 64位浮点有效数中可用的最大53位 - >真实的 - >时间。
此软件包有两个版本。主要定义频率的物理类型,并在Quartus和Vivado(以及任何模拟器)中工作,但不能在XST中工作。精简timing_ops_xilinx删除物理类型以支持XST。逻辑包名称仍为timing_ops
,因此您的代码仍可移植,只需更改库映射。
答案 1 :(得分:2)
我也尝试过这样的计算,但在某些供应商的工具上失败了......我目前的解决方案是使用实常数来表示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不再抱怨此代码。