一.设计目标
对输入时钟信号进行1~N分频。
二.设计思路
从分频数来看,整个设计可分为三部分:1分频、奇数分频、偶数分频。
①1分频:可直接将输入时钟信号进行输出。
②偶数分频:使用一个计数器在上升沿或者下降沿进行计数,计数到N/2时,分频时钟进行跳变。
③奇数分频:由于奇数分频会在输入时钟信号的上升沿或者下降沿进行跳变输出,所以采用两个计数分别对上升沿和下降沿进行计数。
设计原理如上图所示,将奇数N分成三个部分,前(N-1)/2个Tclk、中间一个Tclk、后(N-1)/2个Tclk。从0时刻开始,在时钟下降沿时clk_n置高,在到达中间T时刻时进行置低;同理从0时刻开始,在时钟上升沿时clk_p置高,在到达中间T时刻时进行置低。对两个信号进行整合变得到所需分频时钟,即clk_p或上clk_n的值为clk_div。
完成对这三种情况进行编写代码,再整合到一起,框图如下:
控制模块主要协调三种分频情况,当DIV==奇数时,奇数分频模块工作,偶数分频模块失能;反之同理。选通信号根据DIV的值不同从而选通对应模块。
三.设计代码
①奇数分频
复制代码
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
63module odd_div( clk, rst, enable, div_in, div_clk ); input clk; input rst; input[7:0] div_in; input enable; output div_clk; wire div_clk; reg [7:0]cnt_p,cnt_n; reg clk_p,clk_n; always@(posedge clk or negedge rst) begin if(!rst) begin clk_p <= 0; cnt_p <= 1; end else if(enable) begin if(cnt_p>=div_in)cnt_p <= 1; else cnt_p <= cnt_p + 1; if(cnt_p == 1)clk_p <= ~clk_p; else if(cnt_p == (div_in>>1) + 1 )clk_p <= ~clk_p; else clk_p <= clk_p; end else begin cnt_p <= 1; clk_p <= 0; end end always@(negedge clk or negedge rst) begin if(!rst) begin cnt_n <= 1; clk_n <= 0; end else if(enable) begin if(cnt_n>=div_in)cnt_n <= 1; else cnt_n <= cnt_n + 1; if(cnt_n == 1)clk_n <= ~clk_n; else if(cnt_n == (div_in>>1) + 1 )clk_n <= ~clk_n; else clk_n <= clk_n; end else begin cnt_n <= 1; clk_n <= 0; end end assign div_clk = clk_n | clk_p; endmodule
②偶数分频
复制代码
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
47module even_div( clk, rst, enable, div_in, div_clk ); input clk; input rst; input[7:0] div_in; input enable; output div_clk; reg div_clk; reg[7:0]cnt; always@(posedge clk or negedge rst) begin if(!rst) begin cnt <= 0; div_clk<=0; end else if(enable) begin if(cnt == div_in>>1) begin cnt <= 1; div_clk <= ~div_clk ; end else if(cnt == div_in) begin cnt <= cnt + 1; div_clk <= ~div_clk ; end else begin cnt <= cnt + 1; div_clk <= div_clk; end end else begin cnt <= 0; div_clk <= 0; end end endmodule
③控制
复制代码
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
55module control( clk, rst, div, odd_en, out_div, even_en, clk_1, sel ); input clk; input rst; input [7:0]div; output [7:0]out_div; output odd_en; output even_en; output clk_1; output [1:0]sel; reg odd_en; wire [7:0]out_div; reg even_en; wire clk_1; wire [1:0]sel; assign out_div = div; assign sel = (div==1)?( 0 ) : ( (div[0]==1)? 1 : 2 ); assign clk_1 = (div==1)?(clk ) : ( 0 ); reg[7:0]temp_div,temp_div2; always@(posedge clk) begin temp_div <= div; temp_div2 <= temp_div; if(div != temp_div2) begin odd_en <= 0; even_en <= 0; end else begin if(div[0]==1) begin odd_en <= 1; even_en <= 0; end else begin odd_en <= 0; even_en <= 1; end end end endmodule
④三选一
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18module selet( clk_1, clk_odd, clk_even, sel, clk_out ); input clk_1; input clk_odd; input clk_even; input [1:0]sel; output clk_out; wire clk_out; assign clk_out= (sel==0) ? (clk_1) : ( (sel==1) ? clk_odd : clk_even); endmodule
⑤顶层
复制代码
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
59module top( clk, rst, div, div_clk ); input clk; input rst; input[7:0]div; output div_clk; wire div_clk; wire clk; wire rst; wire [7:0]div; wire [7:0]out_div; wire odd_en; wire even_en; wire clk_1; wire [1:0]sel; control u0( .clk(clk), .rst(rst), .div(div), .out_div(out_div), .odd_en(odd_en), .even_en(even_en), .clk_1(clk_1), .sel(sel) ); wire odd_clk; odd_div u1( .clk(clk), .rst(rst), .enable(odd_en), .div_in(div), .div_clk(odd_clk) ); wire even_clk; even_div u2( .clk(clk), .rst(rst), .enable(even_en), .div_in(div), .div_clk(even_clk) ); selet u3( .clk_1(clk_1), .clk_odd(odd_clk), .clk_even(even_clk), .sel(sel), .clk_out(div_clk) ); endmodule
⑥仿真文件
复制代码
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
31module simulation( ); reg clk; reg rst; reg[7:0] div_in; wire div_clk; initial begin #0 clk=0; rst=0; div_in=1; #300 rst=1; #1000 while(1) begin #500 div_in = div_in + 1; end end top u0( .clk(clk), .rst(rst), .div(div_in), .div_clk(div_clk) ); always #5 clk=~clk; endmodule
四.结果仿真
局部放大图
从时序仿真可以看出,输出分频时钟符合设计。
最后
以上就是从容飞鸟最近收集整理的关于FPGA试题练习--------任意整数分频器设计的全部内容,更多相关FPGA试题练习--------任意整数分频器设计内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复