如何使用fpga取样?

时间:2013-08-08 04:34:53

标签: vhdl fpga spartan

我想从FPGA spartan 3中获取外部数字数据样本。 我想最初采取1000个样本/秒。如何在vhdl编码中选择时钟频率?

感谢。

3 个答案:

答案 0 :(得分:5)

请勿使用计数器生成较低频率的时钟信号。

FPGA中的多个时钟频率会导致各种设计问题,其中一些问题属于“高级主题”的标题,虽然它们可以(如有必要)进行处理和解决,但学习如何使用单个快速时钟既简单又通常更好(同步设计)。

相反,使用FPGA板提供的任何快速时钟,并从中生成较低频率的时序信号,并且 - 至关重要的是 - 将它们用作时钟使能,而不是时钟信号。

DLL,DCM,PLL和其他时钟管理器确实有其用途,但生成1 kHz时钟信号通常不是很好用,即使它们的限制允许。这个应用程序只是急于启用时钟......

另外,不要乱用魔法数字,让VHDL编译器完成工作!我已将时序要求放在一个包中,因此您可以与测试平台以及需要使用它们的任何其他内容共享它们。

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;

我们可以按如下方式编写采样器: (我已将时钟使能分解为一个单独的过程,以阐明时钟使能的使用,但这两个过程可以很容易地合并为一个进一步简化;那么“样本”信号将是不必要的)

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;

答案 1 :(得分:2)

基本时钟必须基于外部时钟,并且不能仅通过Spartan-3 FPGA中的内部资源生成。如果需要,您可以使用Spartan-3 FPGA数字时钟管理器(DCM)资源来缩放外部时钟。合成的VHDL代码本身不能生成时钟。

一旦你有一个更高频率的基本时钟,例如100 MHz,你可以轻松地将其分频,以产生1 kHz的指示,用于外部输入的采样。

答案 2 :(得分:1)

这取决于您可用的时钟频率。如果你有一个20MHz的时钟源,你需要将它除以20000以获得1KHz,你可以用VHDL或者使用DCM来做到这一点。

这是关于如何从20MHz输入创建1kHz时钟的示例:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity clk20Hz is
    Port (
        clk_in : in  STD_LOGIC;
        reset  : in  STD_LOGIC;
        clk_out: out STD_LOGIC
    );
end clk200Hz;

architecture Behavioral of clk20Hz is
    signal temporal: STD_LOGIC;
    signal counter : integer range 0 to 10000 := 0;
begin
    frequency_divider: process (reset, clk_in) begin
        if (reset = '1') then
            temporal <= '0';
            counter <= 0;
        elsif rising_edge(clk_in) then
            if (counter = 10000) then
                temporal <= NOT(temporal);
                counter <= 0;
            else
                counter <= counter + 1;
            end if;
        end if;
    end process;

    clk_out <= temporal;
end Behavioral;