分頻器是用的最廣的一種FPGA電路了,我最初使用的是crazybingo的一個(gè)任意分頻器,可以實(shí)現(xiàn)高精度任意分頻的一個(gè)通用模塊,他的思想在于首先指定計(jì)數(shù)器的位寬比如32位,那么這個(gè)計(jì)數(shù)器的最大值就是2^32=4294967296,
假設(shè)系統(tǒng)時(shí)鐘為50MHz,那么假如要想實(shí)現(xiàn)輸出頻率為fout,那么可以使用的頻率控制字為:
K滿足關(guān)系:
,那么設(shè)計(jì)計(jì)數(shù)器在每個(gè)時(shí)鐘上升沿累加的值為K,當(dāng)計(jì)數(shù)值為2^31時(shí),clkout=1;否則clkout=0.最終即可以實(shí)現(xiàn)任意頻率的輸出,精度的計(jì)算方法為當(dāng)K=1時(shí),可以得到clkout=0.0116415321826934814453125Hz,也即是說(shuō)可以輸出的最小頻率為0.011Hz
此外我們最為常見(jiàn)的分頻器分為以下4種分析:
1.偶數(shù)分頻
最簡(jiǎn)單,要想得到分頻系數(shù)為N的頻率輸出,設(shè)定一個(gè)計(jì)數(shù)器,這個(gè)計(jì)數(shù)器從零開(kāi)始加1,當(dāng)加到N/2-1時(shí)計(jì)數(shù)器清零,或者clkout翻轉(zhuǎn),以此循環(huán),即可實(shí)現(xiàn)偶數(shù)倍分頻。
2.奇數(shù)分頻(分占空比不確定以及占空比50%)
方法一:分頻系數(shù)為N,占總比不確定:以三(N)分頻為例,上升沿觸發(fā)計(jì)數(shù),計(jì)數(shù)器計(jì)數(shù)到1(N-1)/2時(shí)輸出時(shí)鐘翻轉(zhuǎn),計(jì)數(shù)到2(N-1)時(shí)再次翻轉(zhuǎn)。代碼為產(chǎn)生1/11占空比為十一分頻時(shí)鐘:在計(jì)數(shù)值為9和10時(shí)均反轉(zhuǎn)時(shí)鐘,是產(chǎn)生抽樣脈沖的有效方法:
always @(posedge clk or posedge rst) begin
if(rst)begin //復(fù)位
cnt《=0;
clk_div11《=0;
end
elseif(cnt==9) begin
clk_div11《=~clk_div11; //時(shí)鐘翻轉(zhuǎn)
cnt《=cnt+1; //繼續(xù)計(jì)數(shù)
end
elseif(cnt==10) begin
clk_div11《=~clk_div11; //時(shí)鐘翻轉(zhuǎn)
cnt《=0; //計(jì)數(shù)清零
end
else
cnt《=cnt+1;
end
占空比50% ,則可以在上面的基礎(chǔ)上,加上一個(gè)下降沿觸發(fā)計(jì)數(shù),然后將上升沿和下降沿產(chǎn)生的時(shí)鐘進(jìn)行相或運(yùn)算,即可得到奇數(shù)分頻輸出。
reg clk1;
reg[1:0]cnt1;
always@(posedge clk or posedge rst) begin
if(rst)begin //復(fù)位
cnt1《=0;
clk1《=0;
end
elseif(cnt1==1) begin
clk1《=~clk1; //時(shí)鐘翻轉(zhuǎn)
cnt1《=cnt1+1; //繼續(xù)計(jì)數(shù)
end
elseif(cnt1==2) begin
clk1《=~clk1; //時(shí)鐘翻轉(zhuǎn)
cnt1《=0; //計(jì)數(shù)清零
end
else
cnt1《=cnt1+1;
end
reg clk2;
reg[1:0]cnt2;
always@(negedge clk or posedge rst) begin
if(rst)begin //復(fù)位
cnt2《=0;
clk2《=0;
end
elseif(cnt2==1) begin
clk2《=~clk2; //時(shí)鐘翻轉(zhuǎn)
cnt2《=cnt2+1; //繼續(xù)計(jì)數(shù)
end
elseif(cnt2==2) begin
clk2《=~clk2; //時(shí)鐘翻轉(zhuǎn)
cnt2《=0; //計(jì)數(shù)清零
end
else
cnt2《=cnt2+1;
end
assign clk_div3=clk1 | clk2; //或運(yùn)算
方法二:對(duì)進(jìn)行奇數(shù)倍n分頻時(shí)鐘,先進(jìn)行n/2分頻,然后在二分頻得到(這部分先講半整數(shù)分頻)
親測(cè)有效代碼:
module ModuloN_Cntr(input clk,rst,output clk_out);
reg [1:0]cnt1;
reg [1:0]cnt2;
reg temp1,temp2;
always@(posedge clk or negedge rst)
begin
if(~rst)
begin
cnt1《=0;
temp1《=0;
end
else
begin
if(cnt1==2)
begin
temp1《=1;
cnt1《=0;
end
else
begin
cnt1《=cnt1+1;
temp1《=0;
end
end
end
always@(negedge clk or negedge rst)
begin
if(~rst)
begin
cnt2《=0;
temp2《=0;
end
else
begin
if(cnt2==2)
begin
temp2《=1;
cnt2《=0;
end
else
begin
cnt2《=cnt2+1;
temp2《=0;
end
end
end
assign clk_out=temp1|temp2;
endmodule
仿真波形:
3.半整數(shù)分頻
半整數(shù)指的是N+0.5分頻器設(shè)計(jì):先進(jìn)行模N+1計(jì)數(shù),計(jì)數(shù)到N時(shí)輸出時(shí)鐘賦值為1,然后當(dāng)計(jì)數(shù)到0時(shí),輸出時(shí)鐘賦值為0,因此保持計(jì)數(shù)值為N的時(shí)間為半個(gè)時(shí)鐘周期即為設(shè)計(jì)的關(guān)鍵,從中可以發(fā)現(xiàn),計(jì)數(shù)器是在時(shí)鐘的上升沿計(jì)數(shù),那么我們可以讓時(shí)鐘在計(jì)數(shù)值為N時(shí),將計(jì)數(shù)觸發(fā)時(shí)鐘翻轉(zhuǎn),時(shí)鐘的下降沿變?yōu)樯仙?,因此?jì)數(shù)值為0,所以每產(chǎn)生一個(gè)N+0.5分頻時(shí)鐘周期,觸發(fā)時(shí)鐘都要翻轉(zhuǎn)一次,以2.5分頻為例程序如下:
//異或運(yùn)算
assignclk_in=clk^clk_div2;
//模3計(jì)數(shù)器
reg clk_out;
reg [1:0]cnt;
always@(posedge clk_in or posedge rst) begin
if(rst)begin //復(fù)位
cnt《=0;
clk_out《=0;
end
elseif(cnt==1) begin
clk_out《=~clk_out; //時(shí)鐘翻轉(zhuǎn)
cnt《=cnt+1; //繼續(xù)計(jì)數(shù)
end
elseif(cnt==2) begin
clk_out《=~clk_out; //時(shí)鐘翻轉(zhuǎn)
cnt《=0; //計(jì)數(shù)清零
end
else
cnt《=cnt+1;
end
//2分頻
reg clk_div2;
always@(posedge clk_out or posedge rst) begin
if(rst) clk_div2《=0; //復(fù)位
else clk_div2=~clk_div2;
end
那么5.5分頻呢:
代碼:通用的這里N=5;
module ModuloN_Cntr(clk,clk_div,temp1,temp2);//N+0.5
input clk;
output clk_div;
reg[31:0]cnt1=0;
reg[31:0]cnt2=0;
output reg temp1,temp2;
initial begin temp1=0;temp2=1;end //首先進(jìn)行初始化,temp1=0;temp2=1
parameter N=5; //設(shè)定分頻系數(shù)為N+0.5
always @(posedge clk) //temp1上升沿跳變
begin
if(cnt1==2*N) //2*N
begin cnt1[31:0]《=32‘d0;end
else begin cnt1[31:0]《=cnt1[31:0]+32’d1;end
if(cnt1==32‘d0) begin temp1《=1;end //高電平時(shí)間為N+1;
if(cnt1==N+1) begin temp1《=0;end //低電平時(shí)間為N;
end
always@(negedge clk) //temp2下降沿跳變
begin
if(cnt2==2*N) //2*N
begin cnt2[31:0]《=32’d0;end
else begin cnt2[31:0]《=cnt2[31:0]+32‘d1;end
if(cnt2==32’d0) begin temp2《=0;end //低電平時(shí)間為N;
if(cnt2==N) begin temp2《=1;end //高電平時(shí)間為N+1;
end
assign clk_div=temp1&&temp2; //邏輯與
endmodule
//如果要進(jìn)行N+0.5分頻
//思路:總的來(lái)說(shuō)要進(jìn)行N+1+N=2N+1次分頻
//在時(shí)鐘的上升沿和下降沿都進(jìn)行跳變
//上升沿進(jìn)行占空比為N+1比N的時(shí)鐘temp1;
//下降沿進(jìn)行占空比為N比N+1的時(shí)鐘temp2;
//最后div=temp1&&temp2 即可得到所需要的半整數(shù)分頻
仿真波形:
4.任意小數(shù)分頻
小數(shù)分頻器的實(shí)現(xiàn)方法有很多中,但其基本原理都一樣的,即在若干個(gè)分頻周期中采取某種方法使某幾個(gè)周期多計(jì)或少計(jì)一個(gè)數(shù),從而在整個(gè)計(jì)數(shù)周期的總體平均意義上獲得一個(gè)小數(shù)分頻比。一般而言,這種分頻由于分頻輸出的時(shí)鐘脈沖抖動(dòng)很大,故在設(shè)計(jì)中的使用已經(jīng)非常少。但是,這也是可以實(shí)現(xiàn)的。以8.7倍分頻為例,本文僅僅給出雙模前置小數(shù)分頻原理的verilog代碼及其仿真圖(如圖6),具體原理可以參考劉亞海的《基于FPGA的小數(shù)分頻器的實(shí)現(xiàn)》以及毛為勇的《基于FPGA的任意小數(shù)分頻器的設(shè)計(jì)》。
//8分頻
reg clk_div8;
reg[2:0]cnt_div8;
always@(posedge clk or posedge rst) begin
if(rst)begin //復(fù)位
clk_div8《=0;
cnt_div8《=0;
end
elseif(cnt_div8==3‘d7) begin
clk_div8《=1; //置1
cnt_div8《=0;
end
elseif(cnt_div8==3’d0) begin
clk_div8《=0; //置0
cnt_div8《=cnt_div8+1;
end
else
cnt_div8《=cnt_div8+1;
end
//9分頻
reg clk_div9;
reg[3:0]cnt_div9;
always@(posedge clk or posedge rst) begin
if(rst)begin //復(fù)位
clk_div9《=0;
cnt_div9《=0;
end
elseif(cnt_div9==3‘d8) begin
clk_div9《=1; //置1
cnt_div9《=0;
end
elseif(cnt_div9==3’d0) begin
clk_div9《=0; //置0
cnt_div9《=cnt_div9+1;
end
else
cnt_div9《=cnt_div9+1;
end
//控制信號(hào)
parameterDiv8Num=3;
reg ctrl;
reg[3:0]AddValue;
always@(posedge clk or posedge rst) begin
if(rst)begin //復(fù)位
ctrl《=0;
AddValue《=10-7;
end
elseif(AddValue《10) begin
ctrl《=0;
AddValue《=AddValue+Div8Num;
end
else begin
ctrl《=1;
AddValue《=AddValue-10;
end
end
//選擇輸出
reg clk_out;
always @(ctrlor posedge clk or posedge rst) begin
if(rst) clk_out《=0; //復(fù)位
elseif(ctrl) clk_out《=clk_div8;
elseclk_out《=clk_div9;
end
4、總結(jié)分頻器是FPGA的基礎(chǔ),而且在FPGA邏輯電路設(shè)計(jì)的時(shí)候是經(jīng)常使用的,希望大家對(duì)以上的整數(shù)倍分頻和半整數(shù)倍分頻能熟練掌握
原文標(biāo)題:關(guān)于分頻器的FPGA實(shí)現(xiàn)整理思路
文章出處:【微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
責(zé)任編輯:haq
-
FPGA
+關(guān)注
關(guān)注
1625文章
21620瀏覽量
601238 -
分頻器
+關(guān)注
關(guān)注
43文章
447瀏覽量
49752
原文標(biāo)題:關(guān)于分頻器的FPGA實(shí)現(xiàn)整理思路
文章出處:【微信號(hào):zhuyandz,微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論