【原创】基于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

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