時(shí)鐘對(duì)于 FPGA 是非常重要的,但板載晶振提供的時(shí)鐘信號(hào)頻率是固定的,不一定滿
足工程需求,所以分頻和倍頻還是很有必要的。
一、計(jì)數(shù)器分頻
這里通過計(jì)數(shù)的方式來實(shí)現(xiàn)分頻。
1.通過計(jì)數(shù)器來實(shí)現(xiàn)6分頻。兩種方式。第一種直接通過計(jì)數(shù)方式直接獲取獲取。輸入信號(hào)sys_clk和sys_rst_n,輸出分頻的信號(hào)clk_out,還有一個(gè)變量計(jì)數(shù)器cnt。
?cnt:計(jì)數(shù)器說明,要進(jìn)行6分頻,原始信號(hào)6個(gè)周期變一個(gè)周期輸出,輸出6分頻周期的半個(gè)周期占三個(gè)原始時(shí)鐘周期,對(duì)原始時(shí)鐘計(jì)數(shù)3(0 1 2)
module divider_six
(
input wire sys_rst,
input wire sys_clk,
output reg clk_out
);
reg [2:0] cnt;
always@(posedge sys_clk or negedge sys_rst)
if(sys_rst == 1'b0)
cnt <= 2'd0;
else if(cnt == 2'd2)
cnt <= 2'd0;
else
cnt <= cnt+2'd1;
always@(posedge sys_clk or negedge sys_rst)
if(sys_rst == 1'b0)
clk_out <= 1'b0;
else if(cnt == 2'd2)
clk_out <= ~clk_out;
else
clk_out <= clk_out;
endmodule
testbench
`timescale 1ns/1ns
module tb_divider_six();
reg sys_rst;
reg sys_clk;
wire clk_out;
initial
begin
sys_clk = 1'b1;
sys_rst = 1'b0;
#20
sys_rst = 1'b1;
end
always #10 sys_clk = ~sys_clk;
divider_six divider_six_inst
(
.sys_rst(sys_rst),
.sys_clk(sys_clk),
.clk_out(clk_out)
);
endmodule
?此時(shí)輸出時(shí)鐘就是clk_out ,如果直接用clk_out當(dāng)作系統(tǒng)工作時(shí)鐘
//直接使用clk_out作為工作時(shí)鐘
always@(posedge clk_out or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
a <= 0;
else
a <= a + 1;
二、 通過計(jì)數(shù)器控制標(biāo)志信號(hào),通過標(biāo)志信號(hào)當(dāng)作系統(tǒng)工作時(shí)鐘
module divider_six
(
input wire sys_rst,
input wire sys_clk,
output reg clk_flag
);
reg [2:0] cnt;
always@(posedge sys_clk or negedge sys_rst)
if(sys_rst == 1'b0)
cnt <= 2'd0;
else if(cnt == 3'd5)
cnt <= 3'd0;
else
cnt <= cnt+3'd1;
always@(posedge sys_clk or negedge sys_rst)
if(sys_rst == 1'b0)
clk_flag <=1'b0;
else if(cnt == 3'd4)
clk_flag <=1'b1;
else
clk_flag <=1'b0;
endmodule
此時(shí)產(chǎn)生使能信號(hào)flag(實(shí)際還是周期變化的信號(hào)理解為時(shí)鐘,但是不當(dāng)作時(shí)鐘信號(hào)使用,當(dāng)作使能信號(hào)觸發(fā),但是組合邏輯還是用系統(tǒng)源時(shí)鐘)。
//工作時(shí)鐘還是系統(tǒng)時(shí)鐘
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
a <= 1'd0;
else if(clk_flag == 1'b1)
a <= a + 1'b1;
總結(jié):兩種方式的區(qū)別
這里為什么要說明這兩種方式呢?
這里就要說到FPGA中的全局時(shí)鐘網(wǎng)絡(luò),因?yàn)樵?FPGA 中凡是時(shí)鐘信號(hào)都要連接到全局時(shí)鐘網(wǎng)絡(luò)上,全局時(shí)鐘網(wǎng)絡(luò)也稱為全局時(shí)鐘樹,是 FPGA 廠商專為時(shí)鐘路徑而特殊設(shè)計(jì)的,它能夠使時(shí)鐘信號(hào)到達(dá)每個(gè)寄存器的時(shí)間都盡可能相同,以保證更低的時(shí)鐘偏斜(Skew)和抖動(dòng)(Jitter)。然而我們采用第一種方式產(chǎn)生的時(shí)鐘clk_out信號(hào)并沒有連接到全局時(shí)鐘網(wǎng)絡(luò)上,這種做法所衍生的潛在問題在低速系統(tǒng)中不易察覺,而在高速系統(tǒng)中就很容易出現(xiàn)問題,但 sys_clk 則是由外部晶振直接通過管腳連接到了 FPGA 的專用時(shí)鐘管腳上,自然就會(huì)連接到全局時(shí)鐘網(wǎng)絡(luò)上,所以在 sys_clk 時(shí)鐘工作下的信號(hào)要比在 clk_out 時(shí)鐘工作下的信號(hào)更容易在高速系統(tǒng)中保持穩(wěn)定。所以第二種方式相對(duì)來說更加安全。
上述已經(jīng)說到6分頻,屬于偶數(shù)分頻。下面就來介紹奇數(shù)分頻。奇數(shù)分頻采用上述第二種方式來實(shí)現(xiàn)的話,思路和步驟都差不多。我這里介紹一下奇數(shù)分頻采用上述的第一種方式。那么問題又來了,既然上述第一種方式?jīng)]有第二種好,為什么還有講的,哈哈,是的。我記錄他并不是因?yàn)樗暮?,而是因?yàn)檫@里奇數(shù)分頻時(shí)的思路和邏輯思維。這里實(shí)現(xiàn)一個(gè)5分頻
首先是輸入時(shí)鐘和復(fù)位,一個(gè)計(jì)數(shù)器,兩個(gè)變量分頻時(shí)鐘,一個(gè)輸出時(shí)鐘。要實(shí)現(xiàn)N奇數(shù)分頻,計(jì)數(shù)器計(jì)數(shù)到N-1,這里5分頻最大計(jì)數(shù)到4。然后變量clk1初始狀態(tài)為高電平,系統(tǒng)時(shí)鐘上升沿到來時(shí)有效,這里計(jì)數(shù)到2時(shí)拉低,其實(shí)這里可以計(jì)數(shù)到0,1,2,3都是可以的。clk2初始狀態(tài)也是高電平,系統(tǒng)時(shí)鐘下降沿到來時(shí)有效。這里計(jì)數(shù)到與clk1計(jì)數(shù)最大值一致就行,然后clk1與clk2做與運(yùn)算就可以得到輸出5分頻時(shí)鐘clk_out。
兩個(gè)四分頻,計(jì)數(shù)值范圍不一樣,造成相位偏移半個(gè)周期,兩個(gè)四分頻信號(hào)相與,輸出5分頻時(shí)鐘信號(hào),(最好該信號(hào)依然當(dāng)作flag使能信號(hào)使用,在時(shí)序邏輯輸入時(shí)鐘還是使用原始時(shí)鐘)
?
module divider_five
(
input wire sys_clk ,
input wire sys_rst_n ,
output wire clk_out
);
reg [2:0] cnt;
reg clk1;
reg clk2;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt <= 3'd0;
else if(cnt == 3'd4)
cnt <= 3'd0;
else
cnt <= cnt + 1'b1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
clk1 <= 1'b1;
else if(cnt == 3'd2)
clk1 <= 1'b0;
else if(cnt == 3'd4)
clk1 <= 1'b1;
else
clk1 <= clk1;
always@(negedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
clk2 <= 1'b1;
else if(cnt == 3'd2)
clk2 <= 1'b0;
else if(cnt == 3'd4)
clk2 <= 1'b1;
else
clk2 <= clk2;
assign clk_out = clk1 & clk2;
endmodule
?testbench
`timescale 1ns/1ns
module tb_divider_five();
reg sys_clk;
reg sys_rst_n;
wire clk_out;
initial
begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
#30
sys_rst_n <= 1'b1;
end
always #10 sys_clk = ~sys_clk;
divider_five divider_five_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.clk_out (clk_out)
);
endmodule
仿真
分頻系數(shù):50MHz晶振輸入
? ? ? ? 輸出1KHz時(shí)鐘頻率,50_000_000/1000=50_000
? ? ? ? 輸出100KHz時(shí)鐘頻率,50_000_000/100_000=500文章來源:http://www.zghlxwxcb.cn/news/detail-775239.html
來源:有所更改,加入自己理解(175條消息) FPGA——分頻器_fpga分頻器_rοckman的博客-CSDN博客?????https://blog.csdn.net/a17377547725/article/details/125927896文章來源地址http://www.zghlxwxcb.cn/news/detail-775239.html
到了這里,關(guān)于FPGA_分頻(信號(hào)使能分頻與計(jì)數(shù)器分頻)(奇偶分頻)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!