原文出自:分頻器是指使輸出信號頻率為輸入信號頻率整數分之一的電子電路。在許多電子設備中如電子鐘、頻率合成器等,需要各種不同頻率的信號協同工作,常用的方法是以穩定度高的晶體振蕩器為主振源,通過變換得到所需要的各種頻率成分,分頻器是一種主要變換手段。早期的分頻器多為正弦分頻器,隨著數字集成電路的發展,脈沖分頻器(又稱數字分頻器)逐漸取代了正弦分頻器。下面以Verilog HDL 語言為基礎介紹占空比為50%的分頻器。1?偶分頻偶分頻比較簡單,假設為N分頻,只需計數到N/2-1,然后時鐘翻轉、計數清零,如此循環就可以得到N(偶)分頻。代碼如下。module fp_even(clk_out,clk_in,rst);output clk_out;input clk_in;input rst;reg [1:0] cnt;reg clk_out;parameter N=6;?always @ (posedge clk_in or negedge rst)beginif(!rst)?????? begin????????????? cnt <= 0;????????????? clk_out <= 0;?????? endelse begin?????? ?if(cnt==N/2-1)????????????? begin clk_out <= !clk_out; cnt<=0; end?????? ?else????????????? cnt <= cnt + 1;?????? ?endendendmodule可以通過改變參量N的值和計數變量cnt的位寬實現任意偶分頻。偶分頻(N=6)的RTL原理圖:
偶分頻(N=6)的行為仿真結果:
?2?奇分頻?實現奇數(N)分頻,分別用上升沿計數到(N-1)/2,再計數到N-1;用下降沿計數到(N-1)/2,再計數到N-1,得到兩個波形,然后把它們相或即可得到N分頻。代碼如下:module fp_odd(clk_out,clk_p,clk_n,clk_in,rst);output clk_out;output clk_p,clk_n;input clk_in,rst;?reg [2:0] cnt_p,cnt_n;reg clk_p,clk_n;parameter N=5;?always @ (posedge clk_in or negedge rst)begin?????? if(!rst)???? cnt_p <= 0;?????? else? if(cnt_p==N-1)??? cnt_p <=0;????????????? ? else cnt_p <= cnt_p + 1;end?always @ (posedge clk_in or negedge rst)begin??? if(!rst) clk_p <= 0;??? else if(cnt_p==(N-1)/2)????????????? ?clk_p <= !clk_p;?????? else if(cnt_p==N-1)????????????? ?clk_p <= !clk_p;end?always @ (negedge clk_in or negedge rst)begin?????? if(!rst)???? cnt_n <= 0;?????? else? if(cnt_n==N-1)??? cnt_n <=0;????????????? ? else cnt_n <= cnt_n + 1;end?always @ (negedge clk_in or negedge rst)begin??? if(!rst) clk_n <= 0;??? else if(cnt_n==(N-1)/2)????????????? ?clk_n <= !clk_n;?????? else if(cnt_n==N-1)????????????? ?clk_n <= !clk_n;end?assign clk_out = clk_p | clk_n;endmodule?RTL Schematic:?
?Simulate Behavioral Model:
同理,可以通過改變參量N的值和計數變量cnt_p和cnt_n的位寬實現任意奇分頻。?3?任意占空比的任意分頻在verilog程序設計中,我們往往要對一個頻率進行任意分頻,而且占空比也有一定的要求這樣的話,對于程序有一定的要求,現在在前面兩個實驗的基礎上做一個簡單的總結,實現對一個頻率的任意占空比的任意分頻。比如: FPGA系統時鐘是50M Hz,而我們要產生的頻率是880Hz,那么,我們需要對系統時鐘進行分頻。很容易想到用計數的方式來分頻:50000000/880 = 56818。顯然這個數字不是2的整冪次方,那么我們可以設定一個參數,讓它到56818的時候重新計數就可以實現了。程序如下:module div(clk, clk_div);input clk;output clk_div;reg [15:0] counter;always @(posedge clk)if(counter==56817) counter <= 0;else counter <= counter+1;assign clk_div = counter[15];endmodule分頻的應用很廣泛,一般的做法是先用高頻時鐘計數,然后使用計數器的某一位輸出作為工作時鐘進行其他的邏輯設計,上面的程序就是一個體現。下面我們來算一下它的占空比:我們清楚地知道,這個輸出波形在counter為0到32767的時候為低,在32768到56817的時候為高,占空比為40%多一些,如果我們需要占空比為50%,那么我們需要再設定一個參數,使它為56817的一半,使達到它的時候波形翻轉,就可以實現結果了。程序如下:module div(clk, clk_div);input clk;output clk_div;reg [14:0] counter;always @(posedge clk)if(counter==28408) counter <= 0;else counter <= counter+1;reg clk_div;always @(posedge clk)????? ?if(counter==28408) clk_div <= ~clk_div;endmodule繼續讓我們來看如何實現任意占空比,比如還是由50 M分頻產生880Hz,而分頻得到的信號的占空比為30%。56818×30%=17045module div(clk,reset,clk_div,counter);input clk,reset;output clk_div;output [15:0] counter;reg [15:0] counter;reg clk_div;always @(posedge clk)if(!reset) counter <= 0;else if(counter==56817) counter <= 0;else counter <= counter+1;always @(posedge clk)if(!reset) clk_div <= 0;else if(counter<17045) clk_div <= 1;else clk_div <= 0;endmoduleRTL級描述:
仿真結果:
4?小結通過以上幾個例子對比不難發現,借助計數器來實現任意點空比的任意分頻的方法簡單,且用verilog語言進行行為描述時,代碼簡潔、易懂、通用。通過以上的學習,對分頻器有了比較深刻的認識,將在以后的學習中會有廣泛的應用。
?
評論
查看更多