<前注>:设计中尽量还是要避免使用自己计数分频得到的时钟,去使用厂家自带的分频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