任意整数分频Verilog(占空比50%)

程序实现任意整数分频的功能,已在modelsim中通过验证。

 1 //`define N 5
 2 module div_N (
 3      input CLK,  // 基准时钟
 4      output CLK_div_N, // N分频后得到的时钟
 5      input rst
 6     );
 7 wire [31:0] N=5; // ★ N为分频系数,N≥2即可,N的值为CLK除以CLK_div_N后取整(四舍五入)
 8 
 9 /******************** 产生备用时钟1 ***************/
10 reg [31:0] cnt1;
11 reg   CLK_div_N_1;
12 always @ (posedge CLK or negedge rst)
13 begin  
14 if(!rst)
15 begin
16 cnt1<=0;
17 CLK_div_N_1<=0;
18 end
19 else if(N[0]==0) // 如果N为偶数,比N%2==0这种判断方式更节省资源
20    begin
21    if(N==2) // 如果N为2
22     CLK_div_N_1 <= ~CLK_div_N_1;
23    else
24     if(cnt1==((N-2)>>1))   //比cnt1==(N-2)/2这种判断方式更节省资源
25       begin
26        cnt1 <= 0;
27        CLK_div_N_1 <= ~CLK_div_N_1;
28       end
29      else
30       cnt1 <= cnt1+1;
31     end
32   end
33 else // 如果N为奇数
34 if(cnt1==(N-1)/2)
35 begin
36 CLK_div_N_1 <= ~CLK_div_N_1;cnt1<=cnt1+1'b1;
37 end
38 else if(cnt1==N-1) begin cnt1 <= 0;CLK_div_N_1 <= ~CLK_div_N_1;end
39 else
40 cnt1<=cnt1+1'b1;
41   
42 end
43 
44 /*********************** 产生备用时钟2 *********************/
45 wire  CLK0=(N%2)? (~CLK):0; // 如果N为偶数,备用时钟2(CLK_div_N_2)恒为0,即不需要用到此备用时钟
46 reg [31:0] cnt2;
47 reg   CLK_div_N_2;
48 always @ (posedge CLK0 or negedge rst)
49 if(!rst)
50 begin
51 cnt2<=0;
52 CLK_div_N_2<=0;
53 end
54 else 
55 if(cnt2==(N-1)/2)
56 begin
57 CLK_div_N_2 <= ~CLK_div_N_2;cnt2 <= cnt2+1;
58 end
59 else if(cnt2==N-1) begin cnt2 <= 0;CLK_div_N_2 <= ~CLK_div_N_2;end
60 else
61  cnt2 <= cnt2+1;
62   
63 
64 /******************** 产生最终分频时钟************************/
65 assign  CLK_div_N = CLK_div_N_1 | CLK_div_N_2;
66 
67 endmodule 
verilog代码
`timescale 1ns/1ns
module div_N_tb;
reg CLK,rst;
wire CLK_div_N;
div_N U1(
.CLK(CLK),
.CLK_div_N(CLK_div_N),
.rst(rst)
);
initial
begin
CLK=0;
rst=0;
#5 rst=1;
forever
#5 CLK=~CLK;
end

endmodule
TB代码

图1:  9分频电路

图2:  8分频电路

解释:刚程序调好时发现,偶数分频时候,第一个分频后的时钟不是占用原时钟8clk,还以为程序有问题,细想之后,应该是偶数计数器是从0到(N/2)-1计数,每次到(N/2)-1时翻转,而第一次初始情况下cnt就是0,但新时钟却没有翻转,

原文地址:https://www.cnblogs.com/fkl523/p/4046354.html