天天看點

Verilog實作偶數、奇數、半整數、分數(小數)分頻,畫電路圖用D觸發器實作分頻1.偶數分頻2.奇數分頻3.半整數分頻4.分數(小數)分頻

目錄

1.偶數分頻

2.奇數分頻

3.半整數分頻

4.分數(小數)分頻

參考資料:

通常我們說對原時鐘進行N分頻,即分頻後的時鐘的一個周期是原時鐘周期的N倍。N可以為偶數、奇數、半整數、分數(小數)。

1.偶數分頻

Verilog:N為偶數,使用一個計數器循環0-(N-1)進行計數,在N/2-1與N-1分别将輸出取反,即完成了N分頻。

若果采用D觸發器畫出分頻器,單個D觸發器的反向輸出到輸入就構成了一個簡單的2分頻器,以此為基礎,其分頻輸出作為下一級D觸發器的時鐘,如此串聯起來,x個串聯就是2^x分頻,屬于偶數分頻,如圖1[1].

Verilog實作偶數、奇數、半整數、分數(小數)分頻,畫電路圖用D觸發器實作分頻1.偶數分頻2.奇數分頻3.半整數分頻4.分數(小數)分頻

圖1 用D觸發器分頻

2.奇數分頻

Verilog:N為奇數,使用一個計數器循環0-(N-1)進行計數,控制(N-1)/2個高電平,(N+1)/2個低電平,稱為A;然後将此A電平信号延遲半個時鐘周期稱為B,最後輸出C = A|B,即為占空比為50%的奇數分頻器。另一種方案是(N+1)/2個高電平,(N-1)/2個低電平,那麼最後輸出C=A&B。

以C = A|B為例,将A延時半個時鐘周期的方法有2種,方法1是直接使用下降沿的鎖存器對A鎖存得到B,方法2得到B的原理與A相同,不過是在下降沿檢測(假設A是上升沿檢測)。

Verilog實作偶數、奇數、半整數、分數(小數)分頻,畫電路圖用D觸發器實作分頻1.偶數分頻2.奇數分頻3.半整數分頻4.分數(小數)分頻

圖2 奇數分頻波形

采用D觸發器的話,采用方法1,用一個下降沿的D觸發器鎖存A=clkp1得到信号B=clkn1,把信号A和信号B做邏輯“與”就得到了占空比50%的分頻時鐘信号clkout[1]。

Verilog實作偶數、奇數、半整數、分數(小數)分頻,畫電路圖用D觸發器實作分頻1.偶數分頻2.奇數分頻3.半整數分頻4.分數(小數)分頻

圖3奇數分頻

下面給出N為正整數的分頻器設計,主要原理是N[0]=1為奇數分頻,0為偶數分頻。

module practice_demo(
    input clk,
    input arst,
    
    output clk_div
    );   
parameter N = 5;
reg [2:0] cnt;
reg clk_a;
reg clk_b;
wire clk_c;

[email protected](posedge clk or posedge arst)
begin
    if(arst)
        cnt <= 0;
    else if(cnt == N-1)
        cnt <= 0;
    else
        cnt <= cnt + 1;    
end

[email protected](posedge clk or posedge arst)
begin
    if(arst)
        clk_a<= 0;
    else if(cnt == (N-1)/2 || cnt == N-1)
        clk_a<= ~clk_a;
    else
        clk_a<= clk_a;    
end

/*****************方法1**********************/
[email protected](negedge clk or posedge arst)
begin
    if(arst)
        clk_b <= 0;
    else 
        clk_b <= clk_a;
end
/******************方法2********************/
//[email protected](negedge clk or posedge arst)
//begin
//    if(arst)
//        clk_b<= 0;
//    else if(cnt == (N-1)/2 || cnt == N-1)
//        clk_b<= ~clk_b;
//    else
//        clk_b<= clk_b;    
//end
/*********************************************/

assign clk_c = clk_a | clk_b;
//N[0]=1奇數,否則偶數
assign clk_div = N[0] ? clk_c : clk_a;

endmodule
           

3.半整數分頻

說明:占空比非50%

網上廣為流傳的一種分頻結果是,半分頻多出來那半個周期為高電平,其餘為低電平。例如N=5.5,以原時鐘的一半為機關,可以分頻輸出1高10低。原理是用計數器循環計數0-10即11個周期,控制輸出X前6周期高電平,後5周期低電平,然後再使用計數器得到一個下降沿觸發的5低6高的輸出Y,最後輸出Z = X&Y。

Verilog實作偶數、奇數、半整數、分數(小數)分頻,畫電路圖用D觸發器實作分頻1.偶數分頻2.奇數分頻3.半整數分頻4.分數(小數)分頻

圖4半整數分頻的波形

給出Verilog設計:

module for_practice(
input clk,
input arst,
output  clk_div         
    );
parameter N = 5;//5.5分頻
reg[31:0]cnt1;
reg clkx;
reg clky;
[email protected](posedge clk or posedge arst)
begin
    if(arst)
        cnt1 <= 0;
    else if(cnt1 == 2*N)
        cnt1 <= 0;
    else
        cnt1 <= cnt1+ 1;          
end

[email protected](posedge clk or posedge arst)
begin
    if(arst)
        clkx <= 0;
    else if(cnt1 == 2*N)//
        clkx <= 1;
    else if(cnt1 == N)///
        clkx <= 0;          
end

[email protected](negedge clk or posedge arst)
begin
    if(arst)
        clky <= 0;
    else if(cnt1 == 0)///
        clky <= 0;
    else if(cnt1 == N)//
        clky <= 1;          
end

assign clk_div =  clkx & clky;

endmodule 
           

另外一種做法是想得到接近50%的占空比,例如5分頻得到3個高電平,2.5個低電平,其思路是控制clk,使得計數器值等于某一值隻保持半個周期。參考[3]

4.分數(小數)分頻

此部分主要參考[1][2].

說明:占空比非50%

比如8.7分頻。因為沒辦法用計數器表示0.7這種數字,是以就用一個等效的概念來進行8.7分頻,原時鐘87個周期的總時間等于分頻後的時鐘10個周期的總時間;

先做3次8分頻得到時鐘周期數是24,再做7次9(8加1)分頻得到時鐘周期數63,總共就87個時鐘周期;在這87個時鐘周期裡面分頻時鐘跳變20次總共10個周期。分數分頻器的原理可以用下圖來概括。

Verilog實作偶數、奇數、半整數、分數(小數)分頻,畫電路圖用D觸發器實作分頻1.偶數分頻2.奇數分頻3.半整數分頻4.分數(小數)分頻

圖5分數分頻的原理

用整數部分zn(=8)作為一個分頻系數,zn加1(=9)作為另外一個分頻系數組成一個小數分頻器。

根據上面的原理可以列出下面的二進制一次方程組

zn*N+(zn+1)*M=87   ……(1)

N+M=10                    ……(2)

可以解出N和M的值分别是3和7。

ACC計數器設計,在這裡ZN=8:

ACC計數器就是控制做N次ZN分頻和M次ZN+1次分頻,具體控制過程可以分為以下幾種情況:

第1種情況 :先做N次ZN分頻,再做M次ZN+1次分頻;

第2種情況: 先做M次ZN+1次分頻,再做N次ZN分頻;

第3種情況 :把N次ZN分頻平均插入到M次ZN+1分頻中;

第4種情況 :把M次ZN+1次分頻平均插入到N次ZN分頻中。

組合N次ZN分頻和M次ZN+1次分頻的情況很多。第1、2種情況前後時鐘頻率不太均勻,是以相位抖動比較大;

第3、4種情況前後時鐘頻率均勻性稍好,是以相位抖動會減小,是以最終采用3或4。如圖6

Verilog實作偶數、奇數、半整數、分數(小數)分頻,畫電路圖用D觸發器實作分頻1.偶數分頻2.奇數分頻3.半整數分頻4.分數(小數)分頻

圖6分數分頻的幾種控制過程

具體Verilog設計請參考[2].

參考資料:

[1]時鐘分頻系列——偶數分頻 奇數分頻 分數分頻

[2]基于Verilog的偶數、奇數、半整數分頻以及任意分頻器設計