FPGA奇數分頻


 

  <前注>:設計中盡量還是要避免使用自己計數分頻得到的時鍾,去使用廠家自帶的分頻IP(如Vivado中的clock wizard)。

 

>> 偶數分頻比較簡單,這里略過。

>> 對於不要求占空比為50%的奇數分頻,也比較簡單,直接模N計數,期間進行兩次翻轉就可以了。

 

>> 這里重點介紹要求占空比為50%的奇數分頻。

步驟:

  1. 在時鍾上升沿,進行模N計數,選定到某個值(比如選擇1)時翻轉,經過(N-1)/2 個時鍾再進行翻轉,產生一個臨時時鍾clk_p;

  2. 在時鍾下降沿,進行模N計數,選定到某個值(和上升沿選定的值相同)時翻轉,經過(N-1)/2 個時鍾再進行翻轉,產生一個臨時時鍾clk_n;

  3.  輸出時鍾clk_o = clk_p | clk_n;

 

圖解:(假如需要5分頻)

 

  

 

Verilog代碼:

`timescale 1ns/1ps 

module CLK_DIV5(
    input   clk_i,
    input   rst_n,
    output  clk_o
    );
 
    reg [2:0] cnt1,cnt2;
    reg clk_p,clk_n;
           
//*********************
//MAIN CORE
//*********************        
always @(posedge clk_i,negedge rst_n)
    if(!rst_n) begin
        cnt1 <= 3'b0;
        clk_p <= 1'b0;
    end 
    else begin
        if(cnt1 == 3'b100) begin
            cnt1 <= 3'b0;
            clk_p <= clk_p;
        end
        else begin
            cnt1 <= cnt1 + 1'b1;
            if(cnt1 == 3'b1 || cnt1 == 3'b11)
                clk_p <= ~clk_p;
        end
    end

always @(negedge clk_i,negedge rst_n)
    if(!rst_n) begin
        cnt2 <= 3'b0;
        clk_n <= 1'b0;
    end 
    else begin
        if(cnt2 == 3'b100) begin
            cnt2 <= 3'b0;
            clk_n <= clk_n;
        end
        else begin
            cnt2 <= cnt2 + 1'b1;
            if(cnt2 == 3'b1 || cnt2 == 3'b11)
                clk_n <= ~clk_n;
        end
    end
    
    assign clk_o = clk_p | clk_n;
endmodule

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM