FPGA實現任意分頻 為所欲為——教你什么才是真正的任意分頻


一、為啥要說任意分頻

也許FPGA中的第一個實驗應該是分頻實驗,而不是流水燈,或者LCD1602的"Hello World"顯示,因為分頻的思想在FPGA中極為重要。當初安排流水燈,只是為了能讓大家看到效果,來激發您的興趣(MCU的學習也是如此)。

在大部分的教科書中,都會提到如何分頻,包括奇數分頻,偶數分頻,小數分頻等。有些教科書中也會講到任意分頻(半分頻,任意分數分頻)原理,用的是相位與的電路,並不能辦到50%的占空比,也不是很靈活。

但沒有一本教科書會講到精准,淺顯易懂的高精度任意分頻原理(至少Bingo沒看到過),同時也沒有一種設計能用同一個電路實現任意頻率的控制。Bingo對於當年做的任意波形發生器時候的相位累加器原理,從中受到啟發,總結出高精度任意頻率合成的重要思維,在此貢獻給大家,希望對大家有用。

二、任意分頻原理以及性能

1. DDS相位累加器

(1)DDS合成流程

首先講訴DSS(直接頻率合成法)的原理。

DDS是重要的頻率合成方法,在波形發生器中有極其重要的應用。DDS主要由以下幾部分組成:

a) 相位累加器

b) RAM數據讀取

c) D/A轉換器

d) 低通濾波器

見如下流程圖:直接頻率合成法的流程圖,有固定模塊,輸入頻率控制器,輸出固定頻率的波形。

wps_clip_image-29375

此電路最主要模塊是相位累加器,通過相位累加器循環計數,循環讀取RAM的數據,從而得到固定頻率的波形數據。

(2)相位累加器原理

wps_clip_image-29488

相位累加原理流程如上所示:

輸入頻率控制字,根據算法,來實現相位的變化,分析如下所示:

假定FPGA基准頻率為50MHz,即基准頻率:

wps_clip_image-160(MHz)

假定計數器為32位計數器,即wps_clip_image-24696

K為頻率控制字,則相位輸出的頻率為:

wps_clip_image-19237 (1)

wps_clip_image-17519 (2)

根據相位累加原理,以及RAM緩存讀取數據,每一次wps_clip_image-25807的循環,RAM數據間隔K讀取一次。

當K=1的時候,公式能輸出最小頻率,根據公式(1):

wps_clip_image-30306

所以,最小波形頻率步進為0.011655Hz。

當fo=1Hz的時候,根據公式(2)

wps_clip_image-25409

所以,每Hz的增減,K的步進為85.90。

當K=N/2的時候,公式能輸出最大頻率(因為每個CLK跳變一次),此時,根據公式(1),得到wps_clip_image-2765

wps_clip_image-4319

因此,根據頻率控制字K的變化,能輸出及固定頻率的波形。

2. 任意頻率分頻原理

在FPGA中某些應用場合,對頻率要求比較高的情況下,用相位累加器原理來生成固定頻率的方法,未嘗不可。

wps_clip_image-29426

我們規定,對Cnt進行對半50%拆分,具體如下:

(1)當wps_clip_image-28816的時候,wps_clip_image-18980,即低電平;

(2)當wps_clip_image-19540的時候,fo=1,即高電平。

同上:

wps_clip_image-18030

wps_clip_image-3536

wps_clip_image-12165

wps_clip_image-22532

image

在FPGA中應用,Verilog代碼如下所示:

/***************************************************

* Module Name : clk_generator

* Engineer : Crazy Bingo

* Target Device : EP2C8Q208C8

* Tool versions : Quartus II 9.1SP1

* Create Date : 2011-6-25

* Revision : v1.0

* Description :  

**************************************************/

/*************************************************

fc = 50MHz 50*10^6

fo = fc*K/(2^32)

K = fo*(2^32)/fc

= fo*(2^32)/(50*10^6)

**************************************************/

module clk_generator

#

(

parameter FREQ_WORD = 32'd8590 //1KHz

)

(

input clk, //50MHz

input rst_n, //clock reset

output reg clk_out

);

//--------------------------------------

reg [31:0] max_value;

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

max_value <= 1'b0;

else

max_value <= max_value + FREQ_WORD;

end

//--------------------------------------

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

clk_out <= 1'b0;

else

begin

if(max_value < 32'h7FFF_FFFF)

clk_out <= 1'b0;

else

clk_out <= 1'b1;

end

end

endmodule

本代碼由 從DDS相位累加器中,相應移植總結出來的任意頻率分頻原理,本模塊應用在多個對頻率精准度要求比較高的工程中(如UART中,要得到115200Hz的bps,用這種任意分頻的原理來得到精准的方法,一定程度上能夠提高數據傳輸的准確率)。

在DDS中的相位累加器的任意分頻原理,在一般工程中同樣可以應用。在某些應用場合,還是值得考慮的。本應用純屬Bingo個人主觀應用,如有異議,請聯系本人。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM