【原创】DE2实验练习解答—lab5 Clocks and Timers 【Verilog】【Digital Logic】

本练习的主要目的是如何实现和使用一个实时时钟。

Part I 3位BCD计数器

 

    设计一个3位的BCD计数器。其值按秒递增,输出显示在HEX2~0上,用KEY0复位。计数器的控制信号由50MHz的时钟提供。

分析:

  1. 按秒递增计数,所以要把50MHz的时钟分频得到1Hz的脉冲。
  2. 3位BCD计数器,可用1位BCD计数器组合,其计数范围000~999。

Part I 代码如下:

 

  
    
1 /*
2 *(C) yf.x 2010 http://halflife.cnblogs.com
3 *
4 *Complier :Quartus II 9.1
5 *Filename :counter10.v
6 *Description:3-digit BCD counter
7 *Release :06/20/2010 1.0
8 */
9
10 module bcd_counter(CLOCK_50,KEY,HEX2,HEX1,HEX0);
11 output [ 6 : 0 ]HEX2,HEX1,HEX0; // 输出显示
12 input CLOCK_50; // 50MHz时钟
13 input [ 0 : 0 ]KEY; // 复位
14
15 wire clk_1hz; // 1hz时钟信号
16 wire [ 11 : 0 ]cnt; // 计数器输出
17 wire e2,e3;
18 supply1 vdd;
19
20 assign e2 = cnt[ 3 ] & cnt[ 0 ];
21 assign e3 = e2 & (cnt[ 7 ] & cnt[ 4 ]);
22
23 // 分频产生1hz的脉冲
24 div u0(.o_clk(clk_1hz),
25 .i_clk(CLOCK_50),
26 .rst_n(KEY)
27 );
28
29 // 3-digit BCD计数器
30 counter10 u1(.en(vdd),.clk(clk_1hz),.rst_n(KEY),
31 .q(cnt[ 3 : 0 ])
32 );
33 counter10 u2(.en(e2),.clk(clk_1hz),.rst_n(KEY),
34 .q(cnt[ 7 : 4 ])
35 );
36 counter10 u3(.en(e3),.clk(clk_1hz),.rst_n(KEY),
37 .q(cnt[ 11 : 8 ])
38 );
39
40 // 译码显示
41 seg7_lut h0(.oseg(HEX0),
42 .idig(cnt[ 3 : 0 ])
43 );
44 seg7_lut h1(.oseg(HEX1),
45 .idig(cnt[ 7 : 4 ])
46 );
47 seg7_lut h2(.oseg(HEX2),
48 .idig(cnt[ 11 : 8 ])
49 );
50 endmodule
  
    
1 /*
2 *(C) yf.x 2010 http://halflife.cnblogs.com
3 *
4 *Complier :Quartus II 9.1
5 *Filename :counter10.v
6 *Description:1-digit BCD counter
7 *Release :06/20/2010 1.0
8 */
9
10 module counter10(en,clk,rst_n,q);
11 output reg [ 3 : 0 ]q;
12 input en,clk,rst_n;
13
14 always @( posedge clk or negedge rst_n)
15 begin
16 if ( ! rst_n)
17 q <= 4 ' b0;
18 else if ( ! en)
19 q <= q;
20 else if (q == 4 ' b1001)
21 q <= 4 ' b0;
22 else
23 q <= q + 1 ' b1;
24 end
25 endmodule
  
    
seg7_lut.v 和 div.v 略

Part II 时钟

 

    在DE2上实现一个时钟,要求用HEX7~6显示小时(0~23),用HEX5~4显示分钟(0~59),用HEX3~2显示秒钟(0~59),用SW15~0设定时间。

分析:

  1. 基本的时钟功能,时,分,秒分别对应模24和60的计数器。
  2. 由50MHz的时钟分频得到1Hz的脉冲驱动时钟。
  3. 要能设定时间,计数器必须要加载置数的功能。

Part II 代码如下:

  
    
1 /*
2 *(C) yf.x 2010 http://halflife.cnblogs.com
3 *
4 *Complier :Quartus II 9.1
5 *Filename :digitclock.v
6 *Description:Top_level file
7 *Release :06/20/2010 1.0
8 */
9
10 module digiclock(
11 CLOCK_50, // 50MHz时钟
12 SW,
13 KEY,
14 HEX2,
15 HEX3,
16 HEX4,
17 HEX5,
18 HEX6,
19 HEX7
20 );
21 input CLOCK_50;
22 input [ 17 : 0 ]SW;
23 input [ 1 : 0 ]KEY;
24 output [ 6 : 0 ]HEX2,HEX3,HEX4,HEX5,HEX6,HEX7;
25
26 wire clk_1hz; // 1hz时钟信号
27 wire [ 3 : 0 ]w_sq0;
28 wire [ 3 : 0 ]w_sq1;
29 wire [ 3 : 0 ]w_mq0;
30 wire [ 3 : 0 ]w_mq1;
31 wire [ 3 : 0 ]w_hq0;
32 wire [ 3 : 0 ]w_hq1;
33
34 div u0(
35 .o_clk(clk_1hz),
36 .rst_n(KEY[ 0 ]),
37 .i_clk(CLOCK_50)
38 );
39
40 clock u1(
41 .clk(clk_1hz),
42 .rst_n(KEY[ 1 ]), // 复位
43 .en(SW[ 17 ]), // 计数使能
44 .load(SW[ 16 ]), // 置数使能
45 .sd0( 4 ' b0),
46 .sd1( 4 ' b0),
47 .md0(SW[ 3 : 0 ]), // 分的个位置数
48 .md1(SW[ 7 : 4 ]), // 分的十位置数
49 .hd0(SW[ 11 : 8 ]), // 时的个位置数
50 .hd1(SW[ 15 : 12 ]), // 时的十位置数
51 .sq0(w_sq0),
52 .sq1(w_sq1),
53 .mq0(w_mq0),
54 .mq1(w_mq1),
55 .hq0(w_hq0),
56 .hq1(w_hq1)
57 );
58
59 seg7_lut h2(
60 .idig(w_sq0),
61 .oseg(HEX2)
62 );
63 seg7_lut h3(
64 .idig(w_sq1),
65 .oseg(HEX3)
66 );
67 seg7_lut h4(
68 .idig(w_mq0),
69 .oseg(HEX4)
70 );
71 seg7_lut h5(
72 .idig(w_mq1),
73 .oseg(HEX5)
74 );
75 seg7_lut h6(
76 .idig(w_hq0),
77 .oseg(HEX6)
78 );
79 seg7_lut h7(
80 .idig(w_hq1),
81 .oseg(HEX7)
82 );
83
84 endmodule
  
    
1 /*
2 *(C) yf.x 2010 http://halflife.cnblogs.com
3 *
4 *Complier :Quartus II 9.1
5 *Filename :clock.v
6 *Description:A clock circuit
7 *Release :06/20/2010 1.0
8 */
9 module clock(
10 clk,
11 rst_n,
12 en,
13 load,
14 sd0, // 秒的个位预置数
15 sd1, // 秒的十位预置数
16 md0, // 分的个位预置数
17 md1, // 分的十位预置数
18 hd0, // 时的个位预置数
19 hd1, // 时的十位预置数
20 sq0, // 秒的个位输出0-9
21 sq1, // 秒的十位输出0-5
22 mq0, // 分的个位输出0-9
23 mq1, // 分的十位输出0-5
24 hq0, // 时的个位输出0-9
25 hq1, // 时的十位输出0-2
26 co // 整体进位23:59:59
27 );
28 input clk,rst_n,en,load;
29 input [ 3 : 0 ]sd0,sd1,md0,md1,hd0,hd1;
30 output [ 3 : 0 ]sq0,sq1,mq0,mq1,hq0,hq1;
31 output co;
32
33 wire w_clr;
34 wire [ 3 : 0 ]w_md0;
35 wire [ 3 : 0 ]w_md1;
36 reg [ 3 : 0 ]w_hd0;
37 reg [ 3 : 0 ]w_hd1;
38 wire w_sco;
39 wire w_mco;
40 wire w_hco;
41
42 counter60 sec(
43 .clk(clk),
44 .rst_n(w_clr),
45 .load(load),
46 .en(en),
47 .d0(sd0),
48 .d1(sd1),
49 .q0(sq0),
50 .q1(sq1),
51 .co(w_sco)
52 );
53 counter60 min(
54 .clk(clk),
55 .rst_n(w_clr),
56 .load(load),
57 .en(en & w_sco),
58 .d0(w_md0),
59 .d1(w_md1),
60 .q0(mq0),
61 .q1(mq1),
62 .co(w_mco)
63 );
64 counter24 hour(
65 .clk(clk),
66 .rst_n(w_clr),
67 .load(load),
68 .en(en & w_sco & w_mco),
69 .d0(w_hd0),
70 .d1(w_hd1),
71 .q0(hq0),
72 .q1(hq1),
73 .co(w_hco)
74 );
75
76 assign w_clr = rst_n | co; // 复位
77 assign co = w_sco & w_mco & w_hco;
78 assign w_md0 = ( ! load) ? 0 :(md0 < 10 ) ? md0: 9 ; // 置数处理
79 assign w_md1 = ( ! load) ? 0 :(md1 < 6 ) ? md1: 5 ;
80
81 always @(load or hd0 or hd1) // 置数处理
82 begin
83 if ( ! load) begin
84 w_hd0 = 4 ' b0;
85 w_hd1 = 4 ' b0;
86 end
87 else begin
88 if (hd1 <= 1 ) begin
89 w_hd1 = hd1;
90 if (hd0 < 10 )
91 w_hd0 = hd0;
92 else
93 w_hd0 = 4 ' b1001;
94 end
95 else begin
96 w_hd1 = 4 ' b0010;
97 if (hd0 < 4 )
98 w_hd0 = hd0;
99 else
100 w_hd0 = 4 ' b0011;
101 end
102 end
103 end
104
105 endmodule

 

  
    
1 /*
2 *(C) yf.x 2010 http://halflife.cnblogs.com
3 *
4 *Complier :Quartus II 9.1
5 *Filename :counter24.v
6 *Description:A 8-bit counter (00~23)
7 *Release :06/20/2010 1.0
8 */
9
10 module counter24(
11 clk,
12 rst_n,
13 load,
14 en,
15 d0,
16 d1,
17 q0,
18 q1,
19 co
20 );
21 input clk,rst_n,load,en;
22 input [ 3 : 0 ]d0,d1;
23 output reg [ 3 : 0 ]q1,q0;
24 output co;
25
26 assign co = q1[ 1 ] & q0[ 1 ] & q0[ 0 ]; // 0010_0011
27
28 always @( posedge clk )
29 begin
30 if ( ! rst_n)
31 {q1,q0} <= 8 ' h00;
32 else if (load)
33 begin
34 q1 <= d1;
35 q0 <= d0;
36 end
37 else if (en)
38 begin
39 if (q0 == 4 ' b1001)
40 begin
41 q0 <= 4 ' b0;
42 q1 <= q1 + 1 ' b1;
43 end
44 else if ((q1 == 4 ' b0010)&&(q0==4 ' b0011))
45 begin
46 q1 <= 4 ' b0;
47 q0 <= 4 ' b0;
48 end
49 else
50 q0 <= q0 + 1 ' b1;
51 end
52 else
53 begin
54 q1 <= q1;
55 q0 <= q0;
56 end
57 end
58
59 endmodule

 

  
    
1 /*
2 *(C) yf.x 2010 http://halflife.cnblogs.com
3 *
4 *Complier :Quartus II 9.1
5 *Filename :counter60.v
6 *Description:A 8-bit counter (00~59)
7 *Release :06/20/2010 1.0
8 */
9
10 module counter60(
11 clk,
12 rst_n,
13 load, // 置数使能
14 en, // 计数使能
15 d0, // 数据输入低4位(BCD:0-9)
16 d1, // 数据输入高4位(BCD:0-5)
17 q0, // 计数输出低4位(BCD:0-9)
18 q1, // 计数输出高4位(BCD:0-5)
19 co // 进位脉冲(bcd:59)
20 );
21
22 input clk,rst_n,load,en;
23 input [ 3 : 0 ]d0,d1;
24 output reg [ 3 : 0 ]q0,q1;
25 output co;
26
27 assign co = q1[ 2 ] & q1[ 0 ] & q0[ 3 ] & q0[ 0 ]; // 0101_1001
28
29 always @( posedge clk )
30 begin
31 if ( ! rst_n) // 复位
32 {q1,q0} <= 8 ' h00;
33 else if (load) // 置数
34 begin
35 q0 <= d0;
36 q1 <= d1;
37 end
38 else if (en) // 计数
39 begin
40 if (q0 == 4 ' b1001)
41 begin
42 q0 <= 4 ' b0;
43 if (q1 == 4 ' b0101)
44 q1 <= 4 ' b0;
45 else
46 q1 <= q1 + 1 ' b1;
47 end
48 else
49 q0 <= q0 + 1 ' b1;
50 end
51 else
52 begin
53 q1 <= q1;
54 q0 <= q0;
55 end
56 end
57
58 endmodule

 

seg7_lut.v 和 div.v 略

 

Part III 反应时间按测试电路

 

要求:

  1. 按KEY0复位测试电路。
  2. 复位一段时间后,LEDR0亮,4位BCD计数器开始以ms为单位计数。从复位到LEDR0亮之间的时间用

   SW7~0以秒为单位设置。

 3.被测试的人看到LEDR0亮时,立即按下KEY3,LEDR0熄灭,4位BCD计数器停止计数,显示值为反应时间,在HEX3~0上。

 

分析:

  1. 可将要求分为2块,一是4位BCD计数器,计数脉冲为1KHz。一是8-bit计数器,计数脉冲为1Hz。
  2. LEDR0为测试开始的信号,也是BCD计数器计数的起始,可将其与BCD计数器的计数使能连接。8-bit的计数器计数结果不用显示,只需要其计数值等于SW7~0的预置值时,计数停止。同时输出一判断是否相等的信号eq。
  3. KEY3作为测试键,也就是控制bcd计数器的计数停止与否,所以其应与eq相与,控制BCD的计数使能。

 

Part III代码如下:

 

  
    
1 /*
2 *(C) yf.x 2010 http://halflife.cnblogs.com
3 *
4 *Complier :Quartus II 9.1
5 *Filename :reflex_timer.v
6 *Description:A ciucuit for test reflex time
7 *Release :06/20/2010 1.0
8 */
9
10 // =====================top-level-file=========== //
11 module reflex_timer(
12 CLOCK_50, // 50MHz输入时钟
13 KEY0, // 2个计数器的复位
14 KEY3, // 反应时间测试键
15 KEY1, // 分频器的复位
16 SW, // 设置反应前的随机时间0-9999s
17 HEX3,HEX2,HEX1,HEX0, // 输出显示
18 LEDR0 // 测试起始的信号灯
19 );
20
21 input CLOCK_50;
22 input KEY0,KEY3,KEY1;
23 input [ 7 : 0 ] SW;
24 output [ 6 : 0 ]HEX3,HEX2,HEX1,HEX0;
25 output LEDR0;
26
27 wire eq,en,clk_1,clk_1k;
28 wire [ 3 : 0 ] q3,q2,q1,q0;
29 // -----------------------insitiate modules------ //
30 counter_8b u0( // 8-bit counter
31 .clk(clk_1),
32 .rst_n(KEY0),
33 .d(SW),
34 .eq(eq)
35 );
36
37 counter_4_bcd u1( // 4-digit BCD counter
38 .en(en),
39 .rst_n(KEY0),
40 .clk(clk_1k),
41 .q3(q3),
42 .q2(q2),
43 .q1(q1),
44 .q0(q0)
45 );
46 // ---------------------Decoding and disply------- //
47 seg7_lut h0(.oseg(HEX0),
48 .idig(q0)
49 );
50 seg7_lut h1(.oseg(HEX1),
51 .idig(q1)
52 );
53 seg7_lut h2(.oseg(HEX2),
54 .idig(q2)
55 );
56 seg7_lut h3(.oseg(HEX3),
57 .idig(q3)
58 );
59 // ---------------------Freguency divide--------- //
60 div #(.N(50_000_000),.M(24_999_999)) // 1-Hz
61 c0(
62 .o_clk(clk_1),
63 .rst_n(KEY1),
64 .i_clk(CLOCK_50)
65 );
66 div #(.N(50_000),.M(24_999)) // 1K-Hz
67 c1(
68 .o_clk(clk_1k),
69 .rst_n(KEY1),
70 .i_clk(CLOCK_50)
71 );
72
73 assign en = (eq & KEY3); // 反应时间计数器的计数使能
74 assign LEDR0 = en;
75
76 endmodule

 

 

  
    
1 /*
2 *(C) yf.x 2010 http://halflife.cnblogs.com
3 *
4 *Complier :Quartus II 9.1
5 *Filename :counter_4_bcd.v
6 *Description:A 4-digit BCD counter
7 *Release :06/20/2010 1.0
8 */
9
10 // ===============4-digit-BCD-counter============ //
11 module counter_4_bcd(
12 en, // 计数使能
13 rst_n, // 复位
14 clk, // 计数的时钟脉冲
15 q3, // 计数输出
16 q2,
17 q1,
18 q0
19 );
20
21 input en,rst_n,clk;
22 output [ 3 : 0 ] q3,q2,q1,q0;
23
24 wire co0,co1,co2;
25
26 counter_1_bcd c0(.en(en),
27 .rst_n(rst_n),
28 .clk(clk),
29 .q(q0)
30 );
31 counter_1_bcd c1(.en(co0),
32 .rst_n(rst_n),
33 .clk(clk),
34 .q(q1)
35 );
36 counter_1_bcd c2(.en(co1),
37 .rst_n(rst_n),
38 .clk(clk),
39 .q(q2)
40 );
41 counter_1_bcd c3(.en(co2),
42 .rst_n(rst_n),
43 .clk(clk),
44 .q(q3)
45 );
46
47 assign co0 = (q0[ 0 ] & q0[ 3 ]); // q0=4'd9
48 assign co1 = (co0 & (q1[ 0 ] & q1[ 3 ])); // {q1,q0}=8'd99
49 assign co2 = (co0 & co1 & (q2[ 0 ] & q2[ 3 ])); // {q2,q1,q0}=12'd999
50
51 endmodule
52 // =============================================== //
53
54 // ===================1-digit-BCD-counter========= //
55 module counter_1_bcd(
56 en,
57 rst_n,
58 clk,
59 q
60 );
61
62 input en,rst_n,clk;
63 output reg [ 3 : 0 ]q;
64
65 always @( posedge clk)
66 begin
67 if ( ! rst_n)
68 q <= 4 ' b0;
69 else if (en) begin
70 if (q >= 4 ' d9)
71 q <= 4 ' b0;
72 else
73 q <= q + 1 ' b1;
74 end
75 else
76 q <= q;
77 end
78 endmodule
79 // ============================================= //
80

 

 

  
    
1 /*
2 *(C) yf.x 2010 http://halflife.cnblogs.com
3 *
4 *Complier :Quartus II 9.1
5 *Filename :counter_8b.v
6 *Description:A 8-bit counter
7 *Release :06/20/2010 1.0
8 */
9
10 module counter_8b(clk,
11 rst_n,
12 d,
13 eq
14 );
15
16 input clk,rst_n;
17 input [ 7 : 0 ]d;
18 output reg eq;
19 reg [ 7 : 0 ]q;
20
21 always @( posedge clk)
22 begin
23 if ( ! rst_n)
24 q <= 8 ' b0;
25 else if (q == d)
26 q <= q;
27 else
28 q <= q + 1 ' b1;
29 end
30
31 always @(q or d)
32 begin
33 if (q == d)
34 eq = 1 ;
35 else
36 eq = 0 ;
37 end
38
39
40 endmodule

 

 

 

  
    
1 // divider
2 module div(
3 output reg o_clk,
4 input rst_n,
5 input i_clk
6 );
7
8 parameter N = 50_000_000;
9 parameter M = 24_999_999;
10
11 reg [ 25 : 0 ]cnt;
12
13 always @( posedge i_clk or negedge rst_n)
14 begin
15 if ( ! rst_n)
16 cnt <= 26 ' b0;
17 else
18 begin
19 if (cnt == N - 1 )
20 cnt <= 26 ' b0;
21 else
22 cnt <= cnt + 1 ' b1;
23 end
24 end
25 always @( posedge i_clk or negedge rst_n)
26 begin
27 if ( ! rst_n)
28 o_clk <= 0 ;
29 else
30 begin
31 if (cnt <= M)
32 o_clk <= 1 ;
33 else
34 o_clk <= 0 ;
35 end
36 end
37
38 endmodule

 

001 

 图1 4-digit BCD计数器仿真结果

 

 

你可能感兴趣的:(Verilog)