[英]How to take samples using fpga?
我想從FPGA spartan 3外部獲取數字數據的樣本。我最初希望每秒獲取1000樣本。 如何在VHDL編碼中選擇時鍾頻率?
謝謝。
不要使用計數器來產生低頻時鍾信號。
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;
我們可以編寫采樣器,如下所示:(我將時鍾使能分成了一個單獨的過程,以闡明時鍾使能的使用,但是可以將這兩個過程輕松合並為一個,以進行進一步簡化;“采樣”信號將然后是不必要的)
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;
基本時鍾必須基於外部時鍾,並且不能僅通過Spartan-3 FPGA中的內部資源生成。 如果需要,您可以使用Spartan-3 FPGA數字時鍾管理器(DCM)資源來縮放外部時鍾。 合成的VHDL代碼本身無法生成時鍾。
一旦有了一些較高頻率(例如100 MHz)的基本時鍾,就可以輕松地對其進行分頻,以產生1 kHz的指示以用於外部輸入的采樣。
這取決於您可用的時鍾頻率。 如果您有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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.