加载中...

时钟分频设计

奇数分频模块

奇分频需要通过两个时钟共同得到,首先得到分频系数M和计数器值N:

$ M=\frac{时钟输入频率}{时钟输出频率} $

$ N=\frac{M-1}{2} $

3分频测试

分析:

$ M=3 $;$ N=1 $;计数器counter0计数至(M-1)

分别对clk_p以及clk_n做复位初始化为0,这样当它们计数到0或者(M-1)/2的时候分别进行信号的翻转;如果clk_p以及clk_n初始化为0,结果是clk_p | clk_n,如果初始化为1则是clk_p & clk_n

代码

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
module clkdiv3 (
input clk,
input rst,
output wire clk_div3
);
parameter N = 3;

reg [1:0] cnt;
reg clk_p;
reg clk_n;

always @(posedge clk) begin
if (rst) cnt <= 2'b00;
else if (cnt == 2'b10) cnt <= 2'b00;
else cnt <= cnt + 2'b01;
end

always @(posedge clk) begin
if (rst) begin
clk_p <= 0;
end else if (cnt == 2'b00 || cnt == 2'b01) begin
clk_p <= ~clk_p;
end else begin
clk_p <= clk_p;
end
end

always @(negedge clk) begin
if (rst) begin
clk_n <= 0;
end else if (cnt == 2'b00 || cnt == 2'b01) begin
clk_n <= ~clk_n;
end else begin
clk_n <= clk_n;
end
end

assign clk_div3 = clk_p | clk_n;

endmodule

M分频测试(M为奇数)

代码

HDL

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
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/03/08 15:12:50
// Design Name:
// Module Name: clkdiv_Modd
// Project Name:
// Target Devices:
// Tool Versions:
// Description: 此程序用于奇数M分频模块代码
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////


module clkdiv_Modd (
input clk,
input rst,
output clk_divM
);
parameter M = 5; //分频系数
parameter N = (M - 1) / 2; //计数器

reg [N:0] cnt;
reg clk_p;
reg clk_n;

//:计数器:0~M-1
always @(posedge clk) begin
if (rst || cnt == M - 1) cnt <= 0;
else cnt <= cnt + 1;
end

//:时钟上升沿跳变
always @(posedge clk) begin
if (rst) clk_p <= 0;
else if (cnt == 0 || cnt == N) clk_p <= ~clk_p;
else clk_p <= clk_p;
end

//:时钟下降沿跳变
always @(negedge clk) begin
if (rst) clk_n <= 0;
else if (cnt == 0 || cnt == N) clk_n <= ~clk_n;
else clk_n <= clk_n;
end

assign clk_divM = clk_p | clk_n; //@初始值为0时,此处为|;初始值为1时,此处为&

endmodule

Testbench

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
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/03/08 15:26:59
// Design Name:
// Module Name: clk_Modd_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////


module clk_Modd_tb ();
reg clk;
reg rst;

initial begin
clk = 0;
rst = 1;
#20;
rst = 1;
#50;
rst = 0;
end

always #1 clk = ~clk;

wire clk_divM;
clkdiv_Modd u_clkdiv_Modd (
.clk (clk),
.rst (rst),
.clk_divM(clk_divM)
);
endmodule

效果展示

5分频显示

7分频显示

偶数分频模块

分析

偶分频需要通过两个时钟共同得到,首先得到分频系数M和计数器值N:

$ M=\frac{时钟输入频率}{时钟输出频率} $

$ N=\frac{M}{2} $

二分频效果展示

4分频效果展示

代码

HDL

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
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/03/08 15:40:04
// Design Name:
// Module Name: clkdiv_even
// Project Name:
// Target Devices:
// Tool Versions:
// Description: 此程序用于偶数M分频模块代码
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////


module clkdiv_even (
input clk,
input rst,
output clk_divM
);
parameter M = 2; //分频系数
parameter N = M / 2; //计数器

reg [N:0] cnt;
reg clk_div;

//:计数器:0~M-1
always @(posedge clk) begin
if (rst || cnt == M - 1) cnt <= 0;
else cnt <= cnt + 1;
end

//:分频处理,时钟上升沿跳变
always @(posedge clk) begin
if (rst) clk_div <= 0;
else if (cnt == 0 || cnt == N) clk_div <= ~clk_div;
else clk_div <= clk_div;
end

assign clk_divM = clk_div;

endmodule

Testbench

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
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/03/08 15:43:56
// Design Name:
// Module Name: clkdiv_even_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////


module clkdiv_even_tb ();
reg clk;
reg rst;

initial begin
clk = 0;
rst = 1;
#20;
rst = 1;
#50;
rst = 0;
end

always #1 clk = ~clk;

wire clk_divM;
clkdiv_even u_clkdiv_even (
.clk (clk),
.rst (rst),
.clk_divM(clk_divM)
);
endmodule

任意占空比分频

配合任意计数器即可