本实验主要是练习计数器,以及利用计数器分频。
1. 时钟分频
2. 十进制计数器
3. 十六进制计数器
4. Quartus II的编译报告
把DE2上的50MHz的时钟分成以下7种:
在顶层模块(diglab2)里我们把上述分频得到的7个时钟组成的数组叫做myclock。
分频所得的时钟可映射到外部I/O接口,以备他用:
把1Hz-10KHz的时钟接到绿色LED.观察.只有1Hz和10Hz的可辨.
本实验分频的思路很简单,先把50MHz的时钟用50分频分成1MHz,然后再用10分频递推分频,直到1Hz.有点像行波进位加法器的思路,同样,性能应该也不高,后面我们会提到.
2. 十进制计数器
用1Hz的时钟驱动2个十进制的计数器,并将其输出显示在HEX7-6上
2个进位信号分别接到LEDG7和LEDG6.
3. 十六进制计数器
用1Hz的时钟驱动一个十六进制的计数器,其输出显示在HEX0.
4. 本实验完整代码如下:
1 /* File name: diglab2.v
2 * Function: This lab illustrates the use of divide-by-N counters, decimal counters,
3 * and a simple hex counter.
4 * Author: John S. Loomis
5 */
6
7 module diglab2 (
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 display
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 // set all inout port to tri-state
24 assign GPIO_0 = 36 ' hzzzzzzzzz;
25 assign GPIO_1 = 36 ' hzzzzzzzzz;
26
27 wire [ 6 : 0 ] myclock;
28 wire RST;
29 assign RST = KEY[ 0 ];
30
31 // setup clock divider
32 clock_divider cdiv (CLOCK_50, RST, myclock);
33 assign GPIO_0[ 6 : 0 ] = myclock;
34
35 // connect clock divider to green leds
36 assign LEDG[ 4 : 0 ] = myclock[ 4 : 0 ];
37
38 // connect dip switches to red leds
39 assign LEDR[ 17 : 0 ] = SW[ 17 : 0 ];
40
41 // set up counters
42 wire [ 3 : 0 ] digit7, digit6;
43 wire ovr0, ovr1;
44
45 decimal_counter count0 (digit6, ovr0, myclock[ 0 ], RST);
46 decimal_counter count1 (digit7, ovr1, ovr0, RST);
47
48 // map to 7-segment displays
49
50 hex_7seg dsp0 (digit6, HEX6);
51 hex_7seg dsp1 (digit7, HEX7);
52
53 assign LEDG[ 7 ] = ovr1;
54 assign LEDG[ 6 ] = ovr0;
55
56 // turn unused LEDs off
57 assign LEDG[ 8 ] = 1 ' b0;
58 assign LEDG[ 5 ] = 1 ' b0;
59
60 // define a simple hex counter
61 reg [ 3 : 0 ] A;
62 always @( posedge myclock[ 0 ])
63 A <= A + 1 ' b1;
64
65 hex_7seg dsp2 (A, HEX0);
66
67 // blanks remaining digits
68 assign HEX1 = 7 ' b111_1111;
69 assign HEX2 = 7 ' b111_1111;
70 assign HEX3 = 7 ' b111_1111;
71 assign HEX4 = 7 ' b111_1111;
72 assign HEX5 = 7 ' b111_1111;
73
74 endmodule
75
76
1 /* File name: decimal_counter.v
2 */
3
4 module decimal_counter (A, OVERFLOW, CLK, RST);
5 input CLK, RST;
6 output OVERFLOW;
7 output [ 3 : 0 ] A;
8 reg OVERFLOW;
9 reg [ 3 : 0 ] A;
10
11 always @( posedge CLK or negedge RST)
12 if ( ~ RST) begin
13 OVERFLOW <= 1 ' b0;
14 A <= 4 ' b0000;
15 end
16 else if (A < 9 ) begin
17 A <= A + 1 ' b1;
18 OVERFLOW <= 1 ' b0;
19 end
20 else begin
21 A <= 4 ' b0000;
22 OVERFLOW <= 1 ' b1;
23 end
24
25 endmodule
26
1 /* File name: clock_divider.v
2 */
3
4 module clock_divider (CLK, RST, clock);
5 input CLK, RST;
6 output [ 6 : 0 ] clock;
7 wire clk_1MHz, clk_100KHz, clk_10KHz, clk_1KHz, clk_100Hz, clk_10Hz, clk_1Hz;
8
9 assign clock = {clk_1MHz, clk_100KHz, clk_10KHz, clk_1KHz, clk_100Hz, clk_10Hz, clk_1Hz};
10
11 divide_by_50 d6 (clk_1MHz, CLK, RST);
12 divide_by_10 d5 (clk_100KHz, clk_1MHz, RST);
13 divide_by_10 d4 (clk_10KHz, clk_100KHz, RST);
14 divide_by_10 d3 (clk_1KHz, clk_10KHz, RST);
15 divide_by_10 d2 (clk_100Hz, clk_1KHz, RST);
16 divide_by_10 d1 (clk_10Hz, clk_100Hz, RST);
17 divide_by_10 d0 (clk_1Hz, clk_10Hz, RST);
18
19 endmodule
20
21
1 /* File name: divide_by_10.v
2 */
3
4 module divide_by_10 (Q, CLK, RST,);
5 input CLK, RST;
6 output Q;
7 reg Q;
8 reg [ 2 : 0 ] count;
9
10 always @( posedge CLK or negedge RST)
11 begin
12 if ( ~ RST)
13 begin
14 Q <= 1 ' b0;
15 count <= 3 ' b000;
16 end
17 else if (count < 4 )
18 begin
19 count <= count + 1 ' b1;
20 end
21 else
22 begin
23 count <= 3 ' b000;
24 Q <= ~ Q;
25 end
26 end
27
28 endmodule
29
30
1 /* File name: divide_by_50.v
2 */
3
4 module divide_by_50 (Q, CLK, RST);
5 input CLK, RST;
6 output Q;
7 reg Q;
8 reg [ 4 : 0 ] count;
9
10 always @( posedge CLK or negedge RST)
11 begin
12 if ( ~ RST)
13 begin
14 Q <= 1 ' b0;
15 count <= 5 ' b00000;
16 end
17 else if (count < 24 )
18 begin
19 count <= count + 1 ' b1;
20 end
21 else
22 begin
23 count <= 5 ' b00000;
24 Q <= ~ Q;
25 end
26 end
27
28 endmodule
29
1 /* File name : hex_7seg.v
2 */
3
4 module hex_7seg (hex_digit, seg);
5 input [ 3 : 0 ] hex_digit;
6 output [ 6 : 0 ] seg;
7 reg [ 6 : 0 ] seg;
8 // seg = {g,f,e,d,c,b,a};
9 // 0 is on and 1 is off
10
11 always @(hex_digit)
12 case (hex_digit)
13 4 ' h0: seg = ~7 ' h3F;
14 4 ' h1: seg = ~7 ' h06; // ---a----
15 4 ' h2: seg = ~7 ' h5B; // | |
16 4 ' h3: seg = ~7 ' h4F; // f b
17 4 ' h4: seg = ~7 ' h66; // | |
18 4 ' h5: seg = ~7 ' h6D; // ---g----
19 4 ' h6: seg = ~7 ' h7D; // | |
20 4 ' h7: seg = ~7 ' h07; // e c
21 4 ' h8: seg = ~7 ' h7F; // | |
22 4 ' h9: seg = ~7 ' h67; // ---d----
23 4 ' ha: seg = ~7 ' h77;
24 4 ' hb: seg = ~7 ' h7C;
25 4 ' hc: seg = ~7 ' h39;
26 4 ' hd: seg = ~7 ' h5E;
27 4 ' he: seg = ~7 ' h79;
28 4 ' hf: seg = ~7 ' h71;
29 endcase
30
31 endmodule
10分频仿真结果:
10进制计数器仿真结果:
时序分析结果:
本实验分频的思路虽然简单,但由时序分析的结果可知,存在延迟不匹配的情况,建议实际分频时用PLL模块.
1. John S. Loomis, diglab2.http://www.johnloomis.org/digitallab/diglab/diglab2/diglab2.html