2013-08-08 2 views

ответ

2

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

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

+0

Я считаю, что спартанские 3 устройства евроигра не может выводить что-то ниже, чем несколько МГц (если не изменяет память, это ~ 4МГц).. Это говорит о том, что некоторая простая логика включения должна делать трюк. – Doov

+0

@FarhadA Нет. Почему? http://www.xilinx.com/support/documentation/user_guides/ug331.pdf Минимальная входная частота DCM на спартанском 3a-dsp составляет 5 МГц (см. стр. 81 в том же PDF-файле). Минимальный выход clkfx составляет 5 МГц (на ядре 4 МГц). Лучшее, что может сделать деление на spartan 3a-dsp, составляет 16. 5MHz/16 - 312 кГц (так меньше, чем на несколько МГц, но моя точка все еще стоит): В прошлый раз я проверил 1000 Гц * 16 <<< 5 МГц. Если я не пропустил что-то здесь ... – Doov

+0

Ну @Doov вы, кажется, пропустили раздел под «Частотный диапазон входных тактовых импульсов» в разделе «Частотные требования частоты входных сигналов DFS».Если вы посмотрите на это и выполните поиск «Digital Frequency Synthesizer (DFS)», вы увидите, что то, что вы сказали, допустимо только для DLL, но не при использовании «DFS_FREQUENCY_MODE». – FarhadA

1

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

Это из примера о том, как создать 1кГц часы от входа 20MHz:

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; 
+0

Вы уверены, что это делит часы на 20000? –

+0

Ну, он переключает часы каждые 10k циклов, которые дают полный цикл каждые 20k пульса – FarhadA

+2

не каждые 10001 циклов? –

5

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

Множественные тактовые частоты в ПЛИС вызывают множество проблем с дизайном, некоторые из которых подпадают под заголовки «расширенные темы», и, хотя они могут (при необходимости), все решаться и решаться, изучая, как использовать однократные быстрые часы - и более простая, и в целом лучшая практика (синхронный дизайн).

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

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

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

И мы можем написать пробоотборник следующим образом: (я разделить часы включить в отдельный процесс, чтобы уточнить использование часов дает, но эти два процесса могут быть легко в одном лице для некоторых дополнительно упрощение, сигнал «образец» затем будет ненужным)

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; 
Смежные вопросы