Как взять образцы с помощью FPGA?

Я хочу взять образцы цифровых данных, поступающих извне в FPGA spartan 3. Сначала я хочу взять 1000 выборок / сек. Как выбрать тактовую частоту в VHDL-кодировании?

Благодарю.

3 ответа

Не используйте счетчик для генерации тактового сигнала более низкой частоты.

Многочисленные тактовые частоты в FPGA вызывают множество проблем проектирования, некоторые из которых относятся к разделу "расширенные темы", и, хотя они могут (при необходимости) быть рассмотрены и решены, изучение использования одних быстрых часов является и проще, и в целом лучше практиковать (синхронный дизайн).

Вместо этого используйте любую быструю синхронизацию, которую обеспечивает ваша плата ПЛИС, и генерируйте из нее низкочастотные синхронизирующие сигналы, и, что особенно важно, используйте их как тактовые импульсы, а не тактовые сигналы.

Библиотеки DLL, DCM, PLL и другие диспетчеры тактовых импульсов имеют свое применение, но генерация тактовых сигналов 1 кГц, как правило, нецелесообразна, даже если их ограничения позволяют это. Это приложение просто требует включения часов...

Кроме того, не балуйтесь магическими числами, пусть 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;

Базовая тактовая частота должна быть основана на внешней тактовой частоте и не может быть сгенерирована только с помощью внутренних ресурсов в FPGA Spartan-3. При необходимости вы можете использовать ресурсы Диспетчера цифровых часов (DCM) FPGA Spartan-3 для масштабирования внешних часов. Синтезированный код VHDL сам по себе не может генерировать часы.

Если у вас есть базовый тактовый генератор на более высокой частоте, например 100 МГц, вы можете легко разделить его, чтобы сгенерировать индикацию на частоте 1 кГц для выборки внешнего входа.

Это зависит от того, какая тактовая частота у вас есть. Если у вас есть тактовый источник 20 МГц, вам нужно разделить его на 20000, чтобы получить 1 кГц, вы можете сделать это в VHDL или использовать DCM для этого.

Это пример того, как создать тактовую частоту 1 кГц на входе 20 МГц:

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;
Другие вопросы по тегам