【原创】基于Altera DE2的数字实验—001_3 (DE2)(Digital Logical)(Verilog)

Project 3

    本实验实现一个定时器。KEY3可以启动和停止计时。KEY0复位(计数停止)。基本思路就是利用Project 2的分频时钟100Hz驱动十进制的计数器,将4个十进制的计数器串联,那么在HEX3-2上显示的数字就以S递增。

本实验包含以下内容:

1. 顶层模块的设计。

2. 单稳态脉冲的生成。

3. 编译报告。

设计

1. 顶层模块

(1)设置状态变量和计数器

image

image

(2)设计一个4个数字的行波进位十进制计数器

image

image

(3)将计数结果显示在7-segment上

image

(4)使用选通时钟控制计数器

image

(5)使用单稳触发复位信号。

image

(6)用KEY3和KEY0控制状态

image

(7)把state和reset信号显示在绿色led上

image

2. 单稳脉冲生成模块

    当触发信号为高电平时,输出一个周期为1个时钟的脉冲。

image

3. 分析

    本实验要完成一个定时器并不难,因为驱动时钟在Project 2已经做好了。剩下就是调用计数器。但是,要能够在计数的过程中停止,仅仅靠复位就不够了,我们这里配合复位KEY0还用了KEY3,KEY3同样是按键,想要达到的效果是,KEY3按一次,计数停止,再按一次重新开始计数。这样,KEY3就和计数器的复位有关系了(重新开始计数),也和计数器的时钟有关系(计数停止不就是时钟不动了嘛)。所以就有了选通时钟和复位信号的控制。另外,KEY3作为按键,它的状态还是单独用state表示较好,这样不论按的快慢,state根据时钟翻转。再由state产生pulse,KEY3按一次,state翻转一次,而state翻转2次(KEY3按2次),才产生一个pulse,即复位一次。

完整代码:

  
    
1 /* File name: diglab3
2 * Function: This lab implements a timer. KEY3 start s and stops the timer. KEY0 resets
3 * the count (and stops the timer)
4 * Author: John S. Loomis
5 */
6
7   module diglab3 (
8 // clock input (50 MHz)
9   input CLOCK_50,
10 // push buttons
11   input [ 3 : 0 ] KEY,
12 // dpdt switches
13   input [ 17 : 0 ] SW,
14 // 7-seg displays
15   output [ 6 : 0 ] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6, HEX7,
16 // leds
17   output [ 8 : 0 ] LEDG, // led green[8:0]
18   output [ 17 : 0 ] LEDR, // led red[17:0]
19 // gpio connections
20 inout [ 35 : 0 ] GPIO_0, GPIO_1
21 );
22
23 // all inout port turn to tri-state
24 assign GPIO_0 = 36 ' hzzzzzzzzz;
25 assign GPIO_1 = 36 ' hzzzzzzzzz;
26
27 wire RST;
28 assign RST = KEY[ 0 ];
29
30 // setup clock divider
31 wire [ 6 : 0 ] myclock;
32 clock_divider cdiv (CLOCK_50, RST, myclock);
33
34 // send switches to red leds
35 assign LEDR = SW;
36
37 // blank the unused HEX displays
38 assign HEX7 = 7 ' h7f;
39 assign HEX6 = 7 ' h7f;
40 assign HEX5 = 7 ' h7f;
41 assign HEX4 = 7 ' h7f;
42
43 // state variable
44
45 reg state;
46
47 // setup counters
48 wire [ 3 : 0 ] digit3, digit2, digit1, digit0;
49 wire [ 3 : 0 ] ovr;
50
51 wire clock, reset, pulse;
52 assign clock = (state ? myclock[ 2 ]: 1 ' b0);
53
54 assign reset = ( ~ pulse & RST);
55
56 decimal_counter count0 (digit0, ovr[ 0 ], clock, reset);
57 decimal_counter count1 (digit1, ovr[ 1 ], ovr[ 0 ], reset);
58 decimal_counter count2 (digit2, ovr[ 2 ], ovr[ 1 ], reset);
59 decimal_counter count3 (digit3, ovr[ 3 ], ovr[ 2 ], reset);
60
61 // map to 7-segment displays
62
63 hex_7seg dsp0 (digit0, HEX0);
64 hex_7seg dsp1 (digit1, HEX1);
65 hex_7seg dsp2 (digit2, HEX2);
66 hex_7seg dsp3 (digit3, HEX3);
67
68 // use one-pulse to trigger reset
69
70 oneshot pulser (
71 .pulse_out (pulse),
72 .trigger_in (state),
73 .clk (CLOCK_50)
74 );
75
76 always @( negedge KEY[ 3 ] or negedge RST)
77 begin
78 if ( ! RST)
79 state <= 1 ' b0;
80 else
81 state <= ~ state;
82 end
83
84 // map state to green leds
85 assign LEDG[ 0 ] = ~ RST;
86 assign LEDG[ 1 ] = state;
87 assign LEDG[ 8 : 2 ] = 6 ' h00;
88
89 endmodule
90
91
  
    
1 /* File name: oneshot.v
2 */
3
4 module oneshot (
5 output reg pulse_out,
6 input trigger_in,
7 input clk
8 );
9
10 reg delay;
11
12 always @( posedge clk)
13 begin
14 if (trigger_in && ! delay)
15 pulse_out <= 1 ' b1;
16 else
17 pulse_out <= 1 ' b0;
18 delay <= trigger_in;
19 end
20
21 endmodule
22
clock_divider.v
   
     
1 module clock_divider(CLK,RST,clock);
2 input CLK,RST;
3 output [ 6 : 0 ] clock;
4 wire clk_1Mhz,clk_100Khz,clk_10Khz,clk_1Khz,clk_100hz,clk_10hz,clk_1hz;
5
6 assign clock = {clk_1Mhz,clk_100Khz,clk_10Khz,clk_1Khz,clk_100hz,clk_10hz,clk_1hz};
7
8 divide_by_50 d6(clk_1Mhz,CLK,RST);
9 divide_by_10 d5(clk_100Khz,clk_1Mhz,RST);
10 divide_by_10 d4(clk_10Khz,clk_100Khz,RST);
11 divide_by_10 d3(clk_1Khz,clk_10Khz,RST);
12 divide_by_10 d2(clk_100hz,clk_1Khz,RST);
13 divide_by_10 d1(clk_10hz,clk_100hz,RST);
14 divide_by_10 d0(clk_1hz,clk_10hz,RST);
15 endmodule
decimal_counter.v
   
     
1 module decimal_counter(A,OVERFLOW,CLK,RST);
2 input CLK, RST;
3 output OVERFLOW;
4 output [ 3 : 0 ] A;
5 reg OVERFLOW;
6 reg [ 3 : 0 ] A;
7 always @ ( posedge CLK or negedge RST)
8 if ( ~ RST) begin
9 OVERFLOW <= 1 ' b0;
10 A <= 4 ' b0000;
11 end
12 else if (A < 9 ) begin
13 A <= A + 1 ' b1;
14 OVERFLOW <= 1 ' b0;
15 end
16 else begin
17 A <= 4 ' b0000;
18 OVERFLOW <= 1 ' b1;
19 end
20 endmodule
divide_by_10.v
   
     
1 module divide_by_10(Q,CLK,RST);
2 input CLK, RST;
3 output Q;
4 reg Q;
5 reg [ 2 : 0 ] count;
6 always @ ( posedge CLK or negedge RST)
7 begin
8 if ( ~ RST)
9 begin
10 Q <= 1 ' b0;
11 count <= 3 ' b000;
12 end
13 else if (count < 4 )
14 begin
15 count <= count + 1 ' b1;
16 end
17 else
18 begin
19 count <= 3 ' b000;
20 Q <= ~ Q;
21 end
22 end
23 endmodule
divide_by_50
   
     
1 module divide_by_50(Q,CLK,RST);
2 input CLK, RST;
3 output Q;
4 reg Q;
5 reg [ 4 : 0 ] count;
6 always @ ( posedge CLK or negedge RST)
7 begin
8 if ( ~ RST)
9 begin
10 Q <= 1 ' b0;
11 count <= 5 ' b00000;
12 end
13 else if (count < 24 )
14 begin
15 count <= count + 1 ' b1;
16 end
17 else
18 begin
19 count <= 5 ' b00000;
20 Q <= ~ Q;
21 end
22 end
23 endmodule
hex_7seg.v
   
     
1 module hex_7seg(hex_digit,seg);
2 input [ 3 : 0 ] hex_digit;
3 output [ 6 : 0 ] seg;
4 reg [ 6 : 0 ] seg;
5 // seg = {g,f,e,d,c,b,a};
6 // 0 is on and 1 is off
7
8 always @ (hex_digit)
9 case (hex_digit)
10 4 ' h0: seg = 7 ' b1000000;
11 4 ' h1: seg = 7 ' b1111001; // ---a----
12 4 ' h2: seg = 7 ' b0100100; // | |
13 4 ' h3: seg = 7 ' b0110000; // f b
14 4 ' h4: seg = 7 ' b0011001; // | |
15 4 ' h5: seg = 7 ' b0010010; // ---g----
16 4 ' h6: seg = 7 ' b0000010; // | |
17 4 ' h7: seg = 7 ' b1111000; // e c
18 4 ' h8: seg = 7 ' b0000000; // | |
19 4 ' h9: seg = 7 ' b0011000; // ---d----
20 4 ' ha: seg = 7 ' b0001000;
21 4 ' hb: seg = 7 ' b0000011;
22 4 ' hc: seg = 7 ' b1000110;
23 4 ' hd: seg = 7 ' b0100001;
24 4 ' he: seg = 7 ' b0000110;
25 4 ' hf: seg = 7 ' b0001110;
26 endcase
27
28 endmodule

仿真结果:

p3_KEY3

参考

John S. Loomis ,diglab3.http://www.johnloomis.org/digitallab/diglab/diglab3/diglab3.html

你可能感兴趣的:(Verilog)