實(shí)驗(yàn)17:分頻器
實(shí)驗(yàn)?zāi)康?/h2>實(shí)驗(yàn)任務(wù)
設(shè)計(jì)一個(gè)任意整數(shù)分頻器。
本文引用地址:http://butianyuan.cn/article/202310/451444.htm實(shí)驗(yàn)原理
時(shí)鐘信號(hào)的處理是FPGA的特色之一,因此分頻器也是FPGA設(shè)計(jì)中使用頻率非常高的基本設(shè)計(jì)之一。一般在FPGA中都有集成的鎖相環(huán)可以實(shí)現(xiàn)各種時(shí)鐘的分頻和倍頻設(shè)計(jì),但是通過(guò)語(yǔ)言設(shè)計(jì)進(jìn)行時(shí)鐘分頻是最基本的訓(xùn)練,在對(duì)時(shí)鐘要求不高的設(shè)計(jì)時(shí)也能節(jié)省鎖相環(huán)資源。在本實(shí)驗(yàn)中我們將實(shí)現(xiàn)任意整數(shù)的分頻器,分頻的時(shí)鐘保持50%占空比。
1,偶數(shù)分頻:偶數(shù)倍分頻相對(duì)簡(jiǎn)單,比較容易理解。通過(guò)計(jì)數(shù)器計(jì)數(shù)是完全可以實(shí)現(xiàn)的。如進(jìn)行N倍偶數(shù)分頻,那么通過(guò)時(shí)鐘觸發(fā)計(jì)數(shù)器計(jì)數(shù),當(dāng)計(jì)數(shù)器從0計(jì)數(shù)到N/2-1時(shí),輸出時(shí)鐘進(jìn)行翻轉(zhuǎn),以此循環(huán)下去。
2,奇數(shù)分頻: 如果要實(shí)現(xiàn)占空比為50%的奇數(shù)倍分頻,不能同偶數(shù)分頻一樣計(jì)數(shù)器記到一半的時(shí)候輸出時(shí)鐘翻轉(zhuǎn),那樣得不到占空比50%的時(shí)鐘。以待分頻時(shí)鐘CLK為例,如果以偶數(shù)分頻的方法來(lái)做奇數(shù)分頻,在CLK上升沿觸發(fā),將得到不是50%占空比的一個(gè)時(shí)鐘信號(hào)(正周期比負(fù)周期多一個(gè)時(shí)鐘或者少一個(gè)時(shí)鐘);但是如果在CLK下降沿也觸發(fā),又得到另外一個(gè)不是50%占空比的時(shí)鐘信號(hào),這兩個(gè)時(shí)鐘相位正好相差半個(gè)CLK時(shí)鐘周期通過(guò)這兩個(gè)時(shí)鐘信號(hào)進(jìn)行邏輯運(yùn)算我們可以巧妙的得到50%占空比的時(shí)鐘。
總結(jié)如下:對(duì)于實(shí)現(xiàn)占空比為50%的N倍奇數(shù)分頻,首先進(jìn)行上升沿觸發(fā)進(jìn)行模N計(jì)數(shù),計(jì)數(shù)選定到某一個(gè)值進(jìn)行輸出時(shí)鐘翻轉(zhuǎn),然后經(jīng)過(guò)(N-1)/2再次進(jìn)行翻轉(zhuǎn)得到一個(gè)占空比非50%奇數(shù)n分頻時(shí)鐘。再者同時(shí)進(jìn)行下降沿觸發(fā)的模N計(jì)數(shù),到和上升沿觸發(fā)輸出時(shí)鐘翻轉(zhuǎn)選定值相同值時(shí),進(jìn)行輸出時(shí)鐘時(shí)鐘翻轉(zhuǎn),同樣經(jīng)過(guò)(N-1)/2時(shí),輸出時(shí)鐘再次翻轉(zhuǎn)生成占空比非50%的奇數(shù)n分頻時(shí)鐘。兩個(gè)占空比非50%的n分頻時(shí)鐘進(jìn)行邏輯運(yùn)算(正周期多的相與,負(fù)周期多的相或),得到占空比為50%的奇數(shù)n分頻時(shí)鐘。
Verilog HDL建模描述
用行為級(jí)描述任意整數(shù)分頻器
程序清單divide.v
module divide #
( //parameter是verilog里參數(shù)定義
parameter WIDTH = 24, //計(jì)數(shù)器的位數(shù),計(jì)數(shù)的最大值為 2**(WIDTH-1)
parameter N = 12_000_000 //分頻系數(shù),請(qǐng)確保 N<2**(WIDTH-1),否則計(jì)數(shù)會(huì)溢出
)
(
input clk, //clk連接到FPGA的C1腳,頻率為12MH
zinput rst_n, //復(fù)位信號(hào),低有效,
output clkout //輸出信號(hào),可以連接到LED觀察分頻的時(shí)鐘
);
reg [WIDTH-1:0] cnt_p,cnt_n; //cnt_p為上升沿觸發(fā)時(shí)的計(jì)數(shù)器,cnt_n為下降沿觸發(fā)時(shí)的計(jì)數(shù)器
reg clk_p,clk_n; //clk_p為上升沿觸發(fā)時(shí)分頻時(shí)鐘,clk_n為下降沿觸發(fā)時(shí)分頻時(shí)鐘
/**********上升沿觸發(fā)部分**************************************/
//上升沿觸發(fā)時(shí)計(jì)數(shù)器的控制
always @(posedge clk or negedge rst_n) //posedge和negedge是verilog表示信號(hào)上升沿和下降沿
begin //當(dāng)clk上升沿來(lái)臨或者rst_n變低的時(shí)候執(zhí)行一次always里的語(yǔ)句
if(!rst_n)
cnt_p <= 1'b0;
else if(cnt_p == (N-1))
cnt_p <= 1'b0;
else
cnt_p <= cnt_p + 1'b1; //計(jì)數(shù)器一直計(jì)數(shù),當(dāng)計(jì)數(shù)到N-1的時(shí)候清零,這是一個(gè)模N的計(jì)數(shù)器
end
//上升沿觸發(fā)的分頻時(shí)鐘輸出,如果N為奇數(shù)得到的時(shí)鐘占空比不是50%;如果N為偶數(shù)得到的時(shí)鐘占空比為50%
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
clk_p <= 1'b0;
else if(cnt_p < (N>>1)) //N>>1表示右移一位,相當(dāng)于除以2取商
clk_p <= 1'b0;
else
clk_p <= 1'b1; //得到的分頻時(shí)鐘正周期比負(fù)周期多一個(gè)clk時(shí)鐘
end
/*****************下降沿觸發(fā)部分**************************************/
//下降沿觸發(fā)時(shí)計(jì)數(shù)器的控制
always @(negedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_n <= 1'b0;
else if(cnt_n == (N-1))
cnt_n <= 1'b0;
else
cnt_n <= cnt_n + 1'b1;
end
//下降沿觸發(fā)的分頻時(shí)鐘輸出,和clk_p相差半個(gè)clk時(shí)鐘
always @(negedge clk or negedge rst_n)
begin
if(!rst_n)
clk_n <= 1'b0;
else if(cnt_n < (N>>1))
clk_n <= 1'b0;
else
clk_n <= 1'b1; //得到的分頻時(shí)鐘正周期比負(fù)周期多一個(gè)clk時(shí)鐘
end
/*************************************************************************/
wire clk1 = clk; //當(dāng)N=1時(shí),直接輸出clk
wire clk2 = clk_p; //當(dāng)N為偶數(shù)也就是N的最低位為0,N[0]=0,輸出clk_p
wire clk3 = clk_p & clk_n; //當(dāng)N為奇數(shù)也就是N最低位為1,N[0]=1,輸出clk_p&clk_n。正周期多所以是相與
assign clkout = (N==1)? clk1:(N[0]? clk3:clk2); //條件判斷表達(dá)式
endmodule
實(shí)驗(yàn)步驟
設(shè)計(jì)一個(gè)任意整數(shù)分頻器。
本文引用地址:http://butianyuan.cn/article/202310/451444.htm時(shí)鐘信號(hào)的處理是FPGA的特色之一,因此分頻器也是FPGA設(shè)計(jì)中使用頻率非常高的基本設(shè)計(jì)之一。一般在FPGA中都有集成的鎖相環(huán)可以實(shí)現(xiàn)各種時(shí)鐘的分頻和倍頻設(shè)計(jì),但是通過(guò)語(yǔ)言設(shè)計(jì)進(jìn)行時(shí)鐘分頻是最基本的訓(xùn)練,在對(duì)時(shí)鐘要求不高的設(shè)計(jì)時(shí)也能節(jié)省鎖相環(huán)資源。在本實(shí)驗(yàn)中我們將實(shí)現(xiàn)任意整數(shù)的分頻器,分頻的時(shí)鐘保持50%占空比。
1,偶數(shù)分頻:偶數(shù)倍分頻相對(duì)簡(jiǎn)單,比較容易理解。通過(guò)計(jì)數(shù)器計(jì)數(shù)是完全可以實(shí)現(xiàn)的。如進(jìn)行N倍偶數(shù)分頻,那么通過(guò)時(shí)鐘觸發(fā)計(jì)數(shù)器計(jì)數(shù),當(dāng)計(jì)數(shù)器從0計(jì)數(shù)到N/2-1時(shí),輸出時(shí)鐘進(jìn)行翻轉(zhuǎn),以此循環(huán)下去。
2,奇數(shù)分頻: 如果要實(shí)現(xiàn)占空比為50%的奇數(shù)倍分頻,不能同偶數(shù)分頻一樣計(jì)數(shù)器記到一半的時(shí)候輸出時(shí)鐘翻轉(zhuǎn),那樣得不到占空比50%的時(shí)鐘。以待分頻時(shí)鐘CLK為例,如果以偶數(shù)分頻的方法來(lái)做奇數(shù)分頻,在CLK上升沿觸發(fā),將得到不是50%占空比的一個(gè)時(shí)鐘信號(hào)(正周期比負(fù)周期多一個(gè)時(shí)鐘或者少一個(gè)時(shí)鐘);但是如果在CLK下降沿也觸發(fā),又得到另外一個(gè)不是50%占空比的時(shí)鐘信號(hào),這兩個(gè)時(shí)鐘相位正好相差半個(gè)CLK時(shí)鐘周期通過(guò)這兩個(gè)時(shí)鐘信號(hào)進(jìn)行邏輯運(yùn)算我們可以巧妙的得到50%占空比的時(shí)鐘。
總結(jié)如下:對(duì)于實(shí)現(xiàn)占空比為50%的N倍奇數(shù)分頻,首先進(jìn)行上升沿觸發(fā)進(jìn)行模N計(jì)數(shù),計(jì)數(shù)選定到某一個(gè)值進(jìn)行輸出時(shí)鐘翻轉(zhuǎn),然后經(jīng)過(guò)(N-1)/2再次進(jìn)行翻轉(zhuǎn)得到一個(gè)占空比非50%奇數(shù)n分頻時(shí)鐘。再者同時(shí)進(jìn)行下降沿觸發(fā)的模N計(jì)數(shù),到和上升沿觸發(fā)輸出時(shí)鐘翻轉(zhuǎn)選定值相同值時(shí),進(jìn)行輸出時(shí)鐘時(shí)鐘翻轉(zhuǎn),同樣經(jīng)過(guò)(N-1)/2時(shí),輸出時(shí)鐘再次翻轉(zhuǎn)生成占空比非50%的奇數(shù)n分頻時(shí)鐘。兩個(gè)占空比非50%的n分頻時(shí)鐘進(jìn)行邏輯運(yùn)算(正周期多的相與,負(fù)周期多的相或),得到占空比為50%的奇數(shù)n分頻時(shí)鐘。
用行為級(jí)描述任意整數(shù)分頻器
程序清單divide.v
module divide # ( //parameter是verilog里參數(shù)定義 parameter WIDTH = 24, //計(jì)數(shù)器的位數(shù),計(jì)數(shù)的最大值為 2**(WIDTH-1) parameter N = 12_000_000 //分頻系數(shù),請(qǐng)確保 N<2**(WIDTH-1),否則計(jì)數(shù)會(huì)溢出 ) ( input clk, //clk連接到FPGA的C1腳,頻率為12MH zinput rst_n, //復(fù)位信號(hào),低有效, output clkout //輸出信號(hào),可以連接到LED觀察分頻的時(shí)鐘 ); reg [WIDTH-1:0] cnt_p,cnt_n; //cnt_p為上升沿觸發(fā)時(shí)的計(jì)數(shù)器,cnt_n為下降沿觸發(fā)時(shí)的計(jì)數(shù)器 reg clk_p,clk_n; //clk_p為上升沿觸發(fā)時(shí)分頻時(shí)鐘,clk_n為下降沿觸發(fā)時(shí)分頻時(shí)鐘 /**********上升沿觸發(fā)部分**************************************/ //上升沿觸發(fā)時(shí)計(jì)數(shù)器的控制 always @(posedge clk or negedge rst_n) //posedge和negedge是verilog表示信號(hào)上升沿和下降沿 begin //當(dāng)clk上升沿來(lái)臨或者rst_n變低的時(shí)候執(zhí)行一次always里的語(yǔ)句 if(!rst_n) cnt_p <= 1'b0; else if(cnt_p == (N-1)) cnt_p <= 1'b0; else cnt_p <= cnt_p + 1'b1; //計(jì)數(shù)器一直計(jì)數(shù),當(dāng)計(jì)數(shù)到N-1的時(shí)候清零,這是一個(gè)模N的計(jì)數(shù)器 end //上升沿觸發(fā)的分頻時(shí)鐘輸出,如果N為奇數(shù)得到的時(shí)鐘占空比不是50%;如果N為偶數(shù)得到的時(shí)鐘占空比為50% always @(posedge clk or negedge rst_n) begin if(!rst_n) clk_p <= 1'b0; else if(cnt_p < (N>>1)) //N>>1表示右移一位,相當(dāng)于除以2取商 clk_p <= 1'b0; else clk_p <= 1'b1; //得到的分頻時(shí)鐘正周期比負(fù)周期多一個(gè)clk時(shí)鐘 end /*****************下降沿觸發(fā)部分**************************************/ //下降沿觸發(fā)時(shí)計(jì)數(shù)器的控制 always @(negedge clk or negedge rst_n) begin if(!rst_n) cnt_n <= 1'b0; else if(cnt_n == (N-1)) cnt_n <= 1'b0; else cnt_n <= cnt_n + 1'b1; end //下降沿觸發(fā)的分頻時(shí)鐘輸出,和clk_p相差半個(gè)clk時(shí)鐘 always @(negedge clk or negedge rst_n) begin if(!rst_n) clk_n <= 1'b0; else if(cnt_n < (N>>1)) clk_n <= 1'b0; else clk_n <= 1'b1; //得到的分頻時(shí)鐘正周期比負(fù)周期多一個(gè)clk時(shí)鐘 end /*************************************************************************/ wire clk1 = clk; //當(dāng)N=1時(shí),直接輸出clk wire clk2 = clk_p; //當(dāng)N為偶數(shù)也就是N的最低位為0,N[0]=0,輸出clk_p wire clk3 = clk_p & clk_n; //當(dāng)N為奇數(shù)也就是N最低位為1,N[0]=1,輸出clk_p&clk_n。正周期多所以是相與 assign clkout = (N==1)? clk1:(N[0]? clk3:clk2); //條件判斷表達(dá)式 endmodule
評(píng)論