1. 程式人生 > >分頻器的設計-奇偶分頻(轉載:小魚FPGA,這個微信公眾平臺)

分頻器的設計-奇偶分頻(轉載:小魚FPGA,這個微信公眾平臺)

分頻器的設計——奇偶分頻

1、2的n次方分頻實現

如下電路可以實現對CLK的2分頻。原理很簡單,上電覆位先給暫存器一個初始值,然後只有在CLK上升沿CLK_DIV2才會翻轉一次。因此CLK兩個上升沿之後,CLK_DIV2才完成兩次翻轉。

要實現2的n次方分頻可以通過複用n次這個電路。如下所示。

2、偶數倍分頻

方式一:如下所示。通過移位暫存器實現分頻。例如要實現2n倍分頻,則需要用n個暫存器。

優點:不需要其它任何控制邏輯,只需要暫存器加一個反相器。

缺點:當分頻倍數很大時,需要的暫存器也是倍增。當然你也可以採用複用的方式去減少所需暫存器數目,例如,36分頻,可以做兩個6分頻器相連,則所需暫存器為6個,需要的暫存器數大大減少。

方式二:如下圖所示,通過計數器來實現分頻。比如,做一個2n分頻器,則計數器計數從0到n-1,CLK_DIV就翻轉一次。

程式碼如下(分頻數為DIV_NUM=20):

module fre_div #(
    parameter DIV_NUM = 20, // 分頻數為20
    parameter CNT_W_L = 8   // 計數器位寬為8
    )
    (
    input clk,
    input rst_n,
    output reg div_clk    
    );
    
    reg [CNT_W_L - 1 : 0]   div_cnt;
 
    // 計數器   
    always @ (posedge clk or negedge rst_n)
    begin
        if(!rst_n)
        begin
            div_cnt <= 'h0;
        end
        else if(div_cnt != DIV_NUM / 2 - 1)
        begin
            div_cnt <= div_cnt + 1'b1;
        end
        else
        begin
            div_cnt <= 'h0;
        end
    end
    
    // 分頻器
    always @ (posedge clk or negedge rst_n)
    begin
        if(!rst_n)
        begin
            div_clk <= 1'b0;
        end
        else if(div_cnt == DIV_NUM / 2 -1)
        begin 
            div_clk <= ~div_clk;    
        end
    end       
endmodule

模擬波形:

3、奇數倍分頻

如上方式只能實現偶數倍分頻,是因為暫存器都是源時鐘CLK上升沿觸發的,因此DIV_CLK只能在上升沿去發生跳轉,這導致DIV_CLK必定只能是CLK的偶數倍分頻關係(CLK跳轉兩次,DIV_CLK才可能跳轉一次)。  

奇數倍分頻的一種實現方式如下。一路計數器用CLK的非CLK_N控制,一路用CLK控制。最後將兩路的輸出分頻波形相亦或,得到最後的分頻輸出。如果難以理解可以對著最後的波形去看。

Verilog實現如下(分頻數為DIV_NUM=9):

module fre_div #(
    parameter DIV_NUM = 20, // 分頻數為20
    parameter CNT_W_L = 8   // 計數器位寬為8
    )
    (
    input clk,
    input rst_n,
    output reg div_clk    
    );
    
    reg [CNT_W_L - 1 : 0]   div_cnt;
 
    // 計數器   
    always @ (posedge clk or negedge rst_n)
    begin
        if(!rst_n)
        begin
            div_cnt <= 'h0;
        end
        else if(div_cnt != DIV_NUM / 2 - 1)
        begin
            div_cnt <= div_cnt + 1'b1;
        end
        else
        begin
            div_cnt <= 'h0;
        end
    end
    
    // 分頻器
    always @ (posedge clk or negedge rst_n)
    begin
        if(!rst_n)
        begin
            div_clk <= 1'b0;
        end
        else if(div_cnt == DIV_NUM / 2 -1)
        begin 
            div_clk <= ~div_clk;    
        end
    end   
    
endmodule

模擬波形如下:

 

在完成這個部落格的過程中看到一大佬寫的部落格,可以細細研究一下,以下是連結。

https://blog.csdn.net/moon9999/article/details/75020355/