问题描述
我需要控制与我的 FPGA 接口的 ADC 的采样频率。
-
我可以使用 50MSPS、14 位分辨率的 ADC。然后使用 DCM 将 FPGA 源 50MHz 时钟分频为 1MHz、2MHz 和 5MHz,并且每次都使用这些频率作为我的 ADC 的时钟。 或者我可以使用 20MSPS、16 位分辨率的 ADC 并在 DCM 中选择较小的子采样率。哪一个是首选?这是一种正确的思维方式吗?
-
我可以想到这样的事情:
if ((data_rate=1MSPS andrising_edge(clk_1M)) or (data_rate=2MSPS andrising_edge(clk_2M)) or
(data_rate=5MSPS andrising_edge(clk_5M)) ) 然后 //保存子采样的adc数据样本 ADCDATA1(13 downto 0)
这是糟糕的编码吗?!或者完全错误并且无法工作?
解决方法
您没有说明您使用的是哪个系列或 P/N 的 FPGA,但根据经验,大多数 DCM 的频率都有下限。您需要查阅设备的数据表以找到最小输出频率。这可能低至 5 或 6MHz,因此达到 1MHz 或 2MHz 可能是个问题。我过去对低频 ADC 接口(或任何低速率并行/串行接口)所做的工作是运行我的 FPGA vhdl 进程,例如您建议的 ADC 采样率的方便整数倍(例如 20MHz)和然后创建一个也以 20MHz 运行的计数器,它在每个 ADC 采样周期输出一次使能信号。对于 1MHz 采样率,这意味着计数器将从 0 计数到 19,然后重置回零并重复计数序列。当您的计数值达到 19 时,输出一个脉冲并将其称为“clock_enable”。然后在您的 ADC 示例流程中,让您的流程敏感性列表仅对 clk_20M 敏感,并在您的流程主体中仅使用rising_edge(clk_20M),如下所示:
MY_CLK_ENABLER : process(clk_20M)
begin
if rising_edge(clk_20M) then
if (clk_en_count = "10011") then -- count to 19 the reset
clk_en_count <= "00000";
clk_enable <= '1';
else
clk_en_count <= clk_en_count + '1';
clk_enable <= '0';
end if;
end if;
end process;
MY_SUB_SMPL : process(clk_20M)
begin
if rising_edge(clk_20M) then
if (clk_enable = '1') then
ADCDATA1(13 downto 0)<= Data_in(13 downto 0);
end if;
end if;
end process;
此外,如果您使用的是 16 位 ADC,我想使用所有位,但听起来您在某种程度上仅限于使用 16 位中的 14 位。如果这是真的,并且您提供给 ADC 输入的信号占用了设备的满量程输入电压范围,您可能希望将第 15 位降为 2,而不是将第 13 位降为 0,因为仅将低位取为全量程比例输入将导致数字波形被削波。