1、偶数分频
  • 方法

直接使用计数器实现,在计数一半时将时钟翻转即可;

  • 4 分频示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module clk_div_even
#(
parameter DIV = 4
)
(
input clk,
input rstn,
output reg clko
);

reg [DIV/2-1:0] cnt;

always @(posedge clk or negedge rstn)
begin
if(!rstn) begin
cnt <= 0;
clko <= 0;
end else begin
if(cnt == (DIV/2 - 1)) begin
clko <= ~clko;
cnt <= 0;
end else begin
cnt <= cnt + 1;
end
end
end

endmodule
  • 仿真波形:
2、奇数分频
  • 非 50% 占空比

使用计数器,当计数到一半时候进行翻转时钟,当计数到分频值时候再次翻转;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

module clk_div_odd1
#(
parameter DIV = 5
)
(
input clk,
input rstn,
output reg clko
);

reg [DIV-1:0] cnt;

always @(posedge clk or negedge rstn)
begin
if(!rstn) begin
cnt <= 0;
end else begin
if(cnt == (DIV-1)) begin
cnt <= 0;
end
else begin
cnt <= cnt + 1;
end
end
end

always @(posedge clk or negedge rstn)
begin
if(!rstn) begin
clko <= 1'b0;
end else begin
if(cnt == (DIV-1)/2) begin
clko <= ~clko;
end
else if(cnt == (DIV -1)) begin
clko <= ~clko;
end
else begin
clko <= clko;
end
end
end

endmodule

仿真波形:

  • 50% 占空比

上升沿和下降沿分别做分频,将结果进行或操作即可;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
module clk_div_odd2
#(
parameter DIV = 5
)
(
input clk,
input rstn,
output clko
);

//posedge clk
reg [DIV-1:0] pos_cnt;
reg pos_clk;

always @(posedge clk or negedge rstn)
begin
if(!rstn) begin
pos_cnt <= 0;
end else begin
if(pos_cnt == (DIV-1)) begin
pos_cnt <= 0;
end else begin
pos_cnt <= pos_cnt + 1;
end
end
end

always @(posedge clk or negedge rstn)
begin
if(!rstn) begin
pos_clk <= 0;
end else begin
if(pos_cnt == (DIV-1)/2) begin
pos_clk <= ~pos_clk;
end
else if(pos_cnt == (DIV-1)) begin
pos_clk <= ~pos_clk;
end
else begin
pos_clk <= pos_clk;
end
end
end

//negedge clk
reg [DIV-1:0] neg_cnt;
reg neg_clk;

always @(negedge clk or negedge rstn)
begin
if(!rstn) begin
neg_cnt <= 0;
end else begin
if(neg_cnt == (DIV-1)) begin
neg_cnt <= 0;
end else begin
neg_cnt <= neg_cnt + 1;
end
end
end

always @(negedge clk or negedge rstn)
begin
if(!rstn) begin
neg_clk <= 0;
end else begin
if(neg_cnt == (DIV-1)/2) begin
neg_clk <= ~neg_clk;
end
else if(neg_cnt == (DIV-1)) begin
neg_clk <= ~neg_clk;
end
else begin
neg_clk <= neg_clk;
end
end
end

//clk output
assign clko = pos_clk | neg_clk;

endmodule

仿真波形:

3、小数分频

以设计2.6分频为例;

  • 方法:

(1)将小数取分数形式,即 2.6 = 13/5;

(2)因为2.6在2~3之间,因此可以使用2分频和3分频组合实现;

(3)由如下方程进行设计:

1
2
x + y = 5
2x + 3y = 13

求得 x = 2, y = 3 , 即使用2个2分频和3个3分频时钟实现2.6分频;

(4)设计总计数器,范围为 013 计数,那么在 04范围内进行2分频的计数,在5~13范围内进行3分频的计数,然后根据计数生成需要的时钟;

(5)

  • Verilog实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

//clk divider: 2.5 , M/N = 13/5
module clk_div_mn
#(
parameter M = 13,
parameter N = 5
)
(
input clk,
input rstn,
output reg clko
);

parameter DIV_M = 2;
parameter DIV_N = 3;

reg [3:0] cnt;
always @(posedge clk or negedge rstn)
begin
if(!rstn) begin
cnt <= 0;
end else begin
if(cnt == (M-1)) begin
cnt <= 0;
end else begin
cnt <= cnt + 1;
end
end
end

reg [3:0] cnt2;
reg [3:0] cnt3;

parameter CHANGE = 4;

always @(posedge clk or negedge rstn)
begin
if(!rstn) begin
cnt2 <= 0;
cnt3 <= 0;
end else begin
if(cnt <= (CHANGE-1)) begin
cnt3 <= 0;
if(cnt2 == (DIV_M-1)) begin
cnt2 <= 0;
end else begin
cnt2 <= cnt2 + 1;
end
end
else if(cnt > (CHANGE -1)) begin
cnt2 <= 0;
if(cnt3 == (DIV_N -1)) begin
cnt3 <= 0;
end else begin
cnt3 <= cnt3 + 1;
end
end
end
end

always @(posedge clk or negedge rstn)
begin
if(!rstn) begin
clko <= 0;
end else begin
if(cnt < CHANGE) begin
if(cnt2 == 0 || cnt2 == DIV_M/2) begin
clko <= ~clko;
end
else begin
clko <= clko;
end
end
else begin
if(cnt3 == 0 || cnt3 == (DIV_N-1)/2) begin
clko <= ~clko;
end
else begin
clko <= clko;
end
end
end
end

endmodule

  • 仿真波形: