请勿使用计数器生成较低频率的时钟信号.
FPGA中的多个时钟频率会导致各种设计问题,其中一些问题属于"高级主题"的标题,虽然它们可以(如果需要)都可以处理和解决,但学习如何使用单个快速时钟则是既简单又通常更好的做法(同步设计).
相反,使用FPGA板提供的任何快速时钟,并从中生成较低频率的定时信号,并且 - 至关重要的是 - 将它们用作时钟使能,而不是时钟信号.
DLL,DCM,PLL和其他时钟管理器确实有其用途,但生成1 kHz时钟信号通常不是很好用,即使它们的限制允许.这个应用程序只是急于启用时钟...
另外,不要乱用魔法数字,让VHDL编译器完成工作!我已将时序要求放在一个包中,因此您可以与testbench以及需要使用它们的任何其他内容共享它们.
package timing is
-- Change the first two constants to match your system requirements...
constant Clock_Freq : real := 40.0E6;
constant Sample_Rate : real := 1000.0;
-- These are calculated from the above, so stay correct when you make changes
constant Divide : natural := natural(Clock_Freq / Sample_Rate);
-- sometimes you also need a period, e.g. in a testbench.
constant clock_period : time := 1 sec / Clock_Freq;
end package timing;
Run Code Online (Sandbox Code Playgroud)
我们可以按如下方式编写采样器:(我已将时钟使能分解为一个单独的过程,以阐明时钟使能的使用,但这两个过程可以很容易地合并为一个进一步简化;"样本"信号将然后是不必要的)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
use work.timing.all;
entity sampler is
Port (
Clock : in std_logic;
Reset : in std_logic;
ADC_In : in signed(7 downto 0);
-- signed for audio, or unsigned, depending on your app
Sampled : out signed(7 downto 0);
);
end sampler;
architecture Behavioral of Sampler is
signal Sample : std_logic;
begin
Gen_Sample : process (Clock,Reset)
variable Count : natural;
begin
if reset = '1' then
Sample <= '0';
Count := 0;
elsif rising_edge(Clock) then
Sample <= '0';
Count := Count + 1;
if Count = Divide then
Sample <= '1';
Count := 0;
end if;
end if;
end process;
Sample_Data : process (Clock)
begin
if rising_edge(Clock) then
if Sample = '1' then
Sampled <= ADC_In;
end if;
end if;
end process;
end Behavioral;
Run Code Online (Sandbox Code Playgroud)