我正在做这个项目,将输出一个所需的频率。对于大多数频率,我可以生成有效的代码,但当涉及到像300 Hz这样的频率时,我就遇到了麻烦。
下面是我对其中大部分代码的描述:
library ieee;
use ieee.std_logic_1164.all;
entity test is
port(
clk:in std_logic:='0';
clk_o:buffer std_logic:='0'
);
end test;
architecture Behavioral of test is
begin
process(clk)
variable temp:integer range 0 to 1000000:=0;
begin
if(clk'event)then
temp:=temp+1;
if(temp>=1000000)then
clk_o<=not clk_o;
temp:=0;
end if;
end if;
end process;
end Behavioral;
这将产生50 Hz的频率,因为我的现场可编程门阵列的时钟速度是50 MHz。所以首先我试着除以它,但问题是你不能产生300hz,因为50*10^6/300等于166666.667,以此类推。
然后我看到,你可以让时间类型的变量,并使周期持续1/300,但后来我意识到它不符合合成条件,所以它不好用。也适用于实数类型的变量,这使得它比整型变量更精确,但它也不符合综合条件。
所以我没有主意了,如果有人能给我一些提示,我将非常感激。
发布于 2014-12-05 23:52:21
如果你只使用166666,你的速度只会快0.0004%或4ppm。这是一个很小的错误,在实际实现中通常不会有什么问题--您的50 has振荡器可能会有更多的错误。
编辑:正如评论中指出的,晶体振荡器可能有10-20ppm的误差,但还有其他类型的振荡器具有更高或更低的误差(尽管50 the时钟可能是晶体)
如果你真的需要摆脱0.0004%的误差,你可以使用DCM/MMCM/PLL (取决于你的FPGA的能力)首先将50 the的时钟乘以150 the,这将均匀地分配到300 Hz。
正如Brian Drummond提到的,您还可以使用166667 -2计数器来计数到每3个周期中的2个,并在另一个周期中计数到166666,这将避免累积相位误差,如果您试图与理想的300 the信号源保持同相。
没有任何实际振荡器与所宣传的频率完全匹配,这就是为什么RS232频繁地与时钟重新同步(以避免累积相位误差),以及为什么更高速度的传输使用源同步时钟或时钟与数据恢复PLL。
https://stackoverflow.com/questions/27317546
复制相似问题