分頻器介紹
在數電系統設計中,分頻器的應用非常的廣泛,它的功能就是對高頻率的信號進行分頻。分頻器的本質上是加法器的演變,其計數值由分頻系N=fin/fout決定,分頻器輸出的不是普通的計數值,而是根據分頻係數對輸出信號高低電平進行控制。分頻器常用於數字電路中的時鐘分頻,用以得到較低的時鐘信號、選通信號、中斷信號等。分頻器在公司的筆試題是必考題,這裏我們主要介紹幾種分頻器,偶數分頻、奇數分頻。
偶數分頻器
偶數分頻器是指分頻係數爲偶數,分頻係數爲N=2n(n=1,2,3....)。例如,輸入的時鐘信號爲f,那麼偶數分頻器輸出的時鐘信號爲F=f/2n(n=1,2,3....)。
分頻係數爲2的整數次冪的分頻器
- clk_even_div程序接口
名稱 |
方向 |
位寬 |
說明 |
clk |
Input |
1 |
工作時鐘 |
reset |
Input |
1 |
復位信號(active high) |
clk_div |
Output |
1 |
分頻時鐘信號 |
module clk_even_div(
input clk,
input reset,
output reg clk_div=0
);
reg [2:0]cnt_div=0;
//實現計數器計數功能
always @(posedge clk)
begin
if(reset)begin
cnt_div<=3'd0;
clk_div<=1'b0;
end
else if(cnt_div==3'd6)begin
cnt_div<=3'd0;
clk_div<=~clk_div;
end
else begin
cnt_div<=cnt_div+1'b1;
end
end
endmodule
測試文件:
module TB_clkdiv(
);
reg clk;
reg reset;
wire clk_div;
clk_even_div inst_clk_even_div(
.clk (clk),
.reset (reset),
.clk_div (clk_div)
);
initial begin
clk=0;
reset=1;
#100;
reset=0;
end
always #10 clk=~clk;//50M 時鐘
endmodule
仿真結果:
分頻係數不是2的整數次冪的分頻器
對於分頻係數不是2的整數次冪的分頻器來說,我們可以使用計數器實現分頻功能,至需要我們對計數器進行一些控制操作。例如,分頻係數是14,那麼我們就計數到6時對分頻信號就行取反操作就可以了。
clk_even_div程序接口
名稱 |
方向 |
位寬 |
說明 |
clk |
Input |
1 |
工作時鐘 |
reset |
Input |
1 |
復位信號(active high) |
clk_div |
Output |
1 |
分頻時鐘信號 |
測試文件:
仿真結果:
奇數分頻器
奇數分頻器就是分頻係數爲奇數N=2n+1(n=1,2,3.....).如果輸入的時鐘信號爲f,那麼分頻時鐘信號爲f/(2n+1);奇數分頻器在公司筆試中用的最多。
佔空比爲1:1的奇數分頻器
佔空比爲1:1的技術分頻器需要在輸入時鐘信號的下降沿時進行翻轉操作。這種分頻器的設計需要兩個計數器,一個計數器採用時鐘的上升沿觸發,另一個計數器採用時鐘的下降沿觸發;兩個計數器的模和分頻係數相同,然後根據兩個計數器的並行信號輸出決定兩個相應的電平控制信號;最後對兩個電平控制信號進行相應的邏輯運算就可以了。
clk_odd_div程序接口
名稱 |
方向 |
位寬 |
說明 |
clk |
Input |
1 |
工作時鐘 |
reset |
Input |
1 |
復位信號(active high) |
clk_div |
Output |
1 |
分頻時鐘信號 |
module clk_odd_div(
input clk,
input reset,
output clk_even
);
reg [3:0]count1,count2;
reg clka,clkb;
parameter N=5;//改變N的值就可以得到不同的奇分頻的波形(佔空比是1:1的)
assign clk_even=clka|clkb;
///////////////////////////
always @(posedge clk )
begin
if(reset)
begin
count1<=0;
clka<=0;
end
else
begin
if(count1<(N-1))
begin
count1<=count1+1;
if(count1<(N-1)/2)
begin
clka<=0;
end
else if(count1>=(N-1)/2)
begin
clka<=1;
end
end
else
begin
clka<=0;
count1<=0;
end
end
end
////////////////////////////////////
always @(negedge clk )
begin
if(reset)
begin
count2<=0;
clkb<=0;
end
else
begin
if(count2<(N-1))
begin
count2<=count2+1;
if(count2<(N-1)/2)
begin
clkb<=0;
end
else if(count2>=(N-1)/2)
begin
clkb<=1;
end
end
else
begin
clkb<=0;
count2<=0;
end
end
end
endmodule
測試文件
仿真結果