<前注>:設計中盡量還是要避免使用自己計數分頻得到的時鍾,去使用廠家自帶的分頻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