【原创】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计数器仿真结果

原文地址:https://www.cnblogs.com/halflife/p/1761459.html