分頻器簡(jiǎn)介
實(shí)現(xiàn)分頻一般有兩種方法,一種方法是直接使用 PLL 進(jìn)行分頻,比如在 FPGA 或者 ASIC 設(shè)計(jì)中,都可以直接使用 PLL 進(jìn)行分頻。但是這種分頻有時(shí)候受限于 PLL 本身的特性,無(wú)法得到頻率很低的時(shí)鐘信號(hào),比如輸入 100Mhz 時(shí)鐘,很多PLL 都無(wú)法得到 1Mhz 以下的時(shí)鐘信號(hào)。另外一種方法是直接使用 Verilog 代碼來(lái)實(shí)現(xiàn)分頻。
注意:
使用 Verilog 代碼分頻得到的時(shí)鐘信號(hào)盡量不要當(dāng)做其他模塊的輸入時(shí)鐘信號(hào),因?yàn)橥ㄟ^ Verilog 代碼分頻得到的時(shí)鐘信號(hào)默認(rèn)不會(huì)連接到 FPGA 的時(shí)鐘網(wǎng)絡(luò)上,這樣會(huì)導(dǎo)致時(shí)鐘出現(xiàn)偏移和抖動(dòng),在高頻電路中會(huì)影響電路穩(wěn)定性,這種分頻方式一般用于產(chǎn)生外部低速總線的參考時(shí)鐘,如SPI、I2C的參考時(shí)鐘。
偶數(shù)分頻器和奇數(shù)分頻器
根據(jù)分頻器的分頻比例是偶數(shù)還是奇數(shù),可以將其分為偶數(shù)分頻器和奇數(shù)分頻器。
- 偶數(shù)分頻:就是分頻前的頻率和分頻后的頻率比值是偶數(shù),比如一個(gè) 50Mhz 的晶振時(shí)鐘,進(jìn)行二分頻后,就是 50Mhz/2=25Mhz
- 奇數(shù)分頻:就是分配前的頻率和分頻后的頻率比值是奇數(shù)。比如一個(gè) 50Mhz 的晶振時(shí)鐘,進(jìn)行三分頻后,就是 50Mhz/3=16.667Mhz
偶數(shù)分頻實(shí)現(xiàn)
假設(shè) N(N為偶數(shù))分頻,只需計(jì)數(shù)到 N/2-1,然后時(shí)鐘翻轉(zhuǎn)、計(jì)數(shù)器清零,如此循環(huán)就可以得到 N 分頻。舉個(gè)例子,比如晶振時(shí)鐘是 100Mhz 時(shí)鐘,想得到一個(gè) 25Mhz 的時(shí)鐘,那么這個(gè)是一個(gè) 100/25=4 的四分頻設(shè)計(jì),按照我們剛說的計(jì)數(shù)到 4/2-1=1,然后時(shí)鐘翻轉(zhuǎn)、計(jì)數(shù)器清零,就可以得到一個(gè) 25Mhz 的時(shí)鐘。
偶數(shù)分頻 Verilog 代碼
`timescale 1ns / 1ps
module divider4(
input sys_clk,
input sys_rst_n,
output reg out_clk
);
//分頻計(jì)數(shù)器
reg [2:0] count;
//分頻計(jì)數(shù)器,按分頻比/2-1進(jìn)行計(jì)數(shù)
always @(posedge sys_clk) begin
if(!sys_rst_n)
count <= 2'd0;
else if(count < 2'd1)
count <= count + 2'd1;
else
count <= 2'd0;
end
//翻轉(zhuǎn)輸出時(shí)鐘
always @(posedge sys_clk) begin
if(!sys_rst_n)
out_clk<= 1'b0;
else if(count == 2'd1)
out_clk <= ~out_clk;
end
endmodule
奇數(shù)分頻器實(shí)現(xiàn)
同樣假設(shè) N(N為奇數(shù))分頻,計(jì)數(shù)器需要計(jì)數(shù)到 N-1,當(dāng)計(jì)數(shù)器為0時(shí)輸出時(shí)鐘1在輸入時(shí)鐘的上升沿拉低,當(dāng)計(jì)數(shù)器計(jì)數(shù)到 N/2 取整時(shí)輸出時(shí)鐘1在輸入時(shí)鐘的上升沿進(jìn)行拉高,同時(shí)當(dāng)計(jì)數(shù)器為0時(shí)輸出時(shí)鐘2在輸入時(shí)鐘的下降沿拉低,當(dāng)計(jì)數(shù)器計(jì)數(shù)到 N/2 取整時(shí)輸出時(shí)鐘2在輸入時(shí)鐘的下降沿進(jìn)行拉高,將輸出時(shí)鐘1和輸出時(shí)鐘2相與即可得到真正的輸出時(shí)鐘。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-825175.html
奇數(shù)分頻 Verilog 代碼
`timescale 1ns / 1ps
module divider5(
input sys_clk,
input sys_rst_n,
output out_clk
);
//分頻計(jì)數(shù)器
reg [2:0] count;
//上升沿跳變的中間時(shí)鐘
reg out_clk1;
//下降沿跳變的中間時(shí)鐘
reg out_clk2;
//分頻計(jì)數(shù)器,按分頻比-1進(jìn)行計(jì)數(shù)
always @(posedge sys_clk) begin
if(!sys_rst_n)
count <= 3'd0;
else if(count < 3'd4)
count <= count + 3'd1;
else
count <= 3'd0;
end
//輸出時(shí)鐘1
always @(posedge sys_clk) begin
if(!sys_rst_n)
out_clk1 <= 1'b0;
else if(count == 3'd0)
out_clk1 <= 1'b0;
else if(count == 3'd2)
out_clk1 <= 1'b1;
end
//輸出時(shí)鐘2
always @(negedge sys_clk) begin
if(!sys_rst_n)
out_clk2 <= 1'b0;
else if(count == 3'd0)
out_clk2 <= 1'b0;
else if(count == 3'd2)
out_clk2 <= 1'b1;
end
//輸出分頻后的時(shí)鐘
assign out_clk = out_clk1 & out_clk2;
endmodule
任意分頻器實(shí)現(xiàn)
在實(shí)現(xiàn)任意分頻器時(shí)可以利用條件生成語(yǔ)句,當(dāng)模塊例化時(shí)傳入的參數(shù)為偶數(shù)則生成偶數(shù)分頻的代碼,否則生成奇數(shù)分頻的代碼,有關(guān)生成語(yǔ)句相關(guān)的內(nèi)容參考03 Verilog HDL 語(yǔ)法。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-825175.html
任意分頻 Verilog 代碼
`timescale 1ns / 1ps
module divider #(
//參數(shù)列表
parameter COUNT_WIDTH = 3, //內(nèi)部分頻計(jì)數(shù)器寬度
parameter DIV = 5 //分頻系數(shù)
)
(
input sys_clk,
input sys_rst_n,
output reg out_clk
);
//分頻計(jì)數(shù)器
reg [COUNT_WIDTH-1:0] count;
generate
if((DIV % 2) == 0) begin
//偶數(shù)分頻
//按分頻比/2-1進(jìn)行計(jì)數(shù)
always @(posedge sys_clk) begin
if(!sys_rst_n)
count <= 0;
else if(count < (DIV / 2 -1))
count <= count + 1;
else
count <= 0;
end
//翻轉(zhuǎn)輸出時(shí)鐘
always @(posedge sys_clk) begin
if(!sys_rst_n)
out_clk <= 1'b0;
else if(count == (DIV / 2 -1))
out_clk <= ~out_clk;
end
end
else begin
//奇數(shù)分頻
//上升沿跳變的中間時(shí)鐘
reg out_clk1;
//下降沿跳變的中間時(shí)鐘
reg out_clk2;
//按分頻比-1進(jìn)行計(jì)數(shù)
always @(posedge sys_clk) begin
if(!sys_rst_n)
count <= 0;
else if(count < (DIV -1))
count <= count + 1;
else
count <= 0;
end
//輸出時(shí)鐘1
always @(posedge sys_clk) begin
if(!sys_rst_n)
out_clk1 <= 1'b0;
else if(count == 0)
out_clk1 <= 1'b0;
else if(count == (DIV / 2))
out_clk1 <= 1'b1;
end
//輸出時(shí)鐘2
always @(negedge sys_clk) begin
if(!sys_rst_n)
out_clk2 <= 1'b0;
else if(count == 0)
out_clk2 <= 1'b0;
else if(count == (DIV / 2))
out_clk2 <= 1'b1;
end
//輸出分頻后的時(shí)鐘
always @(*) begin
out_clk = out_clk1 & out_clk2;
end
end
endgenerate
endmodule
到了這里,關(guān)于06 分頻器設(shè)計(jì)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!