我正在做这个将输出所需频率的项目。对于大多数频率,我可以制作有效的代码,但是当涉及300赫兹的频率时,我遇到了麻烦。
所以这是我的大部分代码:
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的频率,因为我的FPGA的时钟速度是50 MHz。所以首先我试着划分它,但问题是你不能产生300赫兹因为50 * 10 ^ 6/300是166666.667等等。
然后我看到你可以制作时间类型的变量,并使时间段持续1/300,但后来我意识到它不是合成资格所以它没有用。还有REAL类型的变量,它可以使它比整数变量更准确,但它也不是合成资格。
所以我没有想法,如果有人能给我一些暗示,我会非常感激。
答案 0 :(得分:0)
如果你只使用166666,你的速度只会超过0.0004%或4ppm。这是一个很小的错误,它通常在实际实现中无关紧要 - 你的50MHz振荡器可能有比这更多的错误 [编辑:如评论中所述,晶体振荡器可能有10-20ppm的误差,但还有其他类型的振荡器具有更高或更低的误差(尽管50MHz FPGA时钟可能是晶体)]
如果您确实需要消除0.0004%的误差,可以使用DCM / MMCM / PLL(取决于FPGA的功能)将50MHz时钟首先乘以150MHz,然后均匀分配到300 Hz。
正如布莱恩德拉蒙德提到的那样,你也可以使用0-2计数器在每3个周期中计数到166667 2到166666,如果你试图保持同步一个非常理想的300MHz源。
没有真正的振荡器与广告频率完美匹配的事实是RS232频繁地重新同步到时钟(以避免累积相位误差)以及为什么更高速的传输使用源同步时钟或时钟和数据恢复的原因锁相环。