【原创】DE2 实验练习解答—lab4 counters【verilog】【digital logic】

本练习的目的是使用计数器。

 

Part I 用T触发器实现16-bit的计数器

 

参照图 1所示的4-bit的同步计数器,实现一个16-bit 的计数器。

005

 

代码16-bit counter

 

1 // top-level file
2   module part1(KEY0,SW,HEX3,HEX2,HEX1,HEX0);
3 input KEY0; // 时钟脉冲
4   input [ 1 : 0 ]SW; // 使能&复位
5   output [ 6 : 0 ]HEX3,HEX2,HEX1,HEX0; // 输出显示
6   wire [ 15 : 0 ]q; // 16-bit计数输出
7  
8 counter_16(SW[ 1 ],KEY0,SW[ 0 ],q);
9
10 seg7_lut H0(q[ 3 : 0 ],HEX0);
11 seg7_lut H1(q[ 7 : 4 ],HEX1);
12 seg7_lut H2(q[ 11 : 8 ],HEX2);
13 seg7_lut H3(q[ 15 : 12 ],HEX3);
14
15   endmodule

 

1 // 由T触发器构建的16-bit计数器
2   module counter_16(en,clk,clr,Q);
3 input en,clk,clr;
4 wire [ 15 : 0 ]q;
5 output [ 15 : 0 ]Q;
6 t_ff u0(en,clk,clr,q[ 0 ]);
7 t_ff u1(en & q[ 0 ],clk,clr,q[ 1 ]);
8 t_ff u2(en & q[ 0 ] & q[ 1 ],clk,clr,q[ 2 ]);
9 t_ff u3(en & q[ 0 ] & q[ 1 ] & q[ 2 ],clk,clr,q[ 3 ]);
10 t_ff u4(en & q[ 0 ] & q[ 1 ] & q[ 2 ] & q[ 3 ],clk,clr,q[ 4 ]);
11 t_ff u5(en & q[ 0 ] & q[ 1 ] & q[ 2 ] & q[ 3 ] & q[ 4 ],clk,clr,q[ 5 ]);
12 t_ff u6(en & q[ 0 ] & q[ 1 ] & q[ 2 ] & q[ 3 ] & q[ 4 ] & q[ 5 ],clk,clr,q[ 6 ]);
13 t_ff u7(en & q[ 0 ] & q[ 1 ] & q[ 2 ] & q[ 3 ] & q[ 4 ] & q[ 5 ] & q[ 6 ],clk,clr,q[ 7 ]);
14 t_ff u8(en & q[ 0 ] & q[ 1 ] & q[ 2 ] & q[ 3 ] & q[ 4 ] & q[ 5 ] & q[ 6 ] & q[ 7 ],clk,clr,q[ 8 ]);
15 t_ff u9(en & q[ 0 ] & q[ 1 ] & q[ 2 ] & q[ 3 ] & q[ 4 ] & q[ 5 ] & q[ 6 ] & q[ 7 ] & q[ 8 ],
16 clk,clr,q[ 9 ]);
17 t_ff u10(en & q[ 0 ] & q[ 1 ] & q[ 2 ] & q[ 3 ] & q[ 4 ] & q[ 5 ] & q[ 6 ] & q[ 7 ] & q[ 8 ] & q[ 9 ],
18 clk,clr,q[ 10 ]);
19 t_ff u11(en & q[ 0 ] & q[ 1 ] & q[ 2 ] & q[ 3 ] & q[ 4 ] & q[ 5 ] & q[ 6 ] & q[ 7 ] & q[ 8 ] & q[ 9 ] & q[ 10 ],
20 clk,clr,q[ 11 ]);
21 t_ff u12(en & q[ 0 ] & q[ 1 ] & q[ 2 ] & q[ 3 ] & q[ 4 ] & q[ 5 ] & q[ 6 ] & q[ 7 ] & q[ 8 ] & q[ 9 ] & q[ 10 ] & q[ 11 ],
22 clk,clr,q[ 12 ]);
23 t_ff u13(en & q[ 0 ] & q[ 1 ] & q[ 2 ] & q[ 3 ] & q[ 4 ] & q[ 5 ] & q[ 6 ] & q[ 7 ] & q[ 8 ] & q[ 9 ] & q[ 10 ] & q[ 11 ] & q[ 12 ],
24 clk,clr,q[ 13 ]);
25 t_ff u14(en & q[ 0 ] & q[ 1 ] & q[ 2 ] & q[ 3 ] & q[ 4 ] & q[ 5 ] & q[ 6 ] & q[ 7 ] & q[ 8 ] & q[ 9 ] & q[ 10 ] & q[ 11 ] & q[ 12 ] & q[ 13 ],
26 clk,clr,q[ 14 ]);
27 t_ff u15(en & q[ 0 ] & q[ 1 ] & q[ 2 ] & q[ 3 ] & q[ 4 ] & q[ 5 ] & q[ 6 ] & q[ 7 ] & q[ 8 ] & q[ 9 ] & q[ 10 ] & q[ 11 ] & q[ 12 ] & q[ 13 ] & q[ 14 ],
28 clk,clr,q[ 15 ]);
29
30 assign Q = q;
31
32   endmodule

 

1 // T flip flop
2   module t_ff(t,clk,rst_n,q);
3 input t,clk,rst_n;
4 output reg q;
5
6 always @( posedge clk)
7 begin
8 if ( ! rst_n)
9 q <= 0 ;
10 else
11 begin
12 if (t == 1 ' b1)
13   q <=~ q;
14 else
15 q <= q;
16 end
17 end
18
19   endmodule

 

001

图2 Fmax值

002

图3 占用的LE数量

 

 

 

 

 

Part II 用赋值语句实现16-bit计数器

 

代码

 

1 // counter-16bit
2   module part2(clk,rst_n,q);
3 input clk,rst_n;
4 output reg [ 15 : 0 ]q;
5
6 always @( posedge clk)
7 begin
8 if ( ! rst_n)
9 q <= 1 ' b0;
10   else
11 begin
12 if (q == 65535 )
13 q <= 0 ;
14 else
15 q <= q + 1 ;
16 end
17 end
18
19   endmodule

 

001

图4 16-bit计数器的RTL视图

 

002

图5 Fmax值

003

图6 16-bit计数器占用的LE

 

 

 

Part III 用LPM实现16-bit计数器

 

代码

 

1 // Top-level file
2   module counter_lpm(en,clk,clr,q);
3 input en,clk,clr;
4 output [ 15 : 0 ]q;
5
6 megcounter counter_16bit(.clock(clk),.cnt_en(en),.sclr(clr),
7 .q(q)
8 );
9 endmodule

 

1 // synopsys translate_off
2 `timescale 1 ps / 1 ps
3 // synopsys translate_on
4 module megcounter (
5 clock,
6 cnt_en,
7 sclr,
8 q);
9
10 input clock;
11 input cnt_en;
12 input sclr;
13 output [ 15 : 0 ] q;
14
15 wire [ 15 : 0 ] sub_wire0;
16 wire [ 15 : 0 ] q = sub_wire0[ 15 : 0 ];
17
18 lpm_counter lpm_counter_component (
19 .sclr (sclr),
20 .clock (clock),
21 .cnt_en (cnt_en),
22 .q (sub_wire0),
23 .aclr ( 1 ' b0),
24 .aload ( 1 ' b0),
25 .aset ( 1 ' b0),
26 .cin ( 1 ' b1),
27 .clk_en ( 1 ' b1),
28 .cout (),
29 .data ({ 16 { 1 ' b0}}),
30 .eq (),
31 .sload ( 1 ' b0),
32 .sset ( 1 ' b0),
33 .updown ( 1 ' b1));
34 defparam
35 lpm_counter_component.lpm_direction = " UP " ,
36 lpm_counter_component.lpm_port_updown = " PORT_UNUSED " ,
37 lpm_counter_component.lpm_type = " LPM_COUNTER " ,
38 lpm_counter_component.lpm_width = 16 ;
39
40
41 endmodule

 

001

图7 用LPM实现16-bit计数器所占用的LE

 

Part IV 循环显示0-9

 

在HEX0上循环显示0-9,每秒刷新一次。

代码

 

1 // top-level file
2 module seg_number(
3 output [ 6 : 0 ]HEX0,
4 input CLOCK_50,
5 input [ 0 : 0 ]KEY
6 );
7
8 wire clk_1hz;
9 reg [ 3 : 0 ]cnt;
10
11 div u0(
12 .o_clk(clk_1hz),
13 .i_clk(CLOCK_50),
14 .rst_n(KEY)
15 );
16
17 always @( posedge clk_1hz or negedge KEY)
18 begin
19 if ( ! KEY)
20 cnt <= 4 ' b0;
21 else
22 begin
23 if (cnt == 4 ' d9)
24 cnt <= 4 ' b0;
25 else
26 cnt <= cnt + 1 ' b1;
27 end
28 end
29
30 seg7_lut u1(
31 .oseg(HEX0),
32 .idig(cnt[ 3 : 0 ])
33 );
34 endmodule
35
36 // divider
37 module div(
38 output reg o_clk,
39 input rst_n,
40 input i_clk
41 );
42
43 parameter N = 50_000_000;
44 parameter M = 24_999_999;
45
46 reg [ 25 : 0 ]cnt;
47
48 always @( posedge i_clk or negedge rst_n)
49 begin
50 if ( ! rst_n)
51 cnt <= 26 ' b0;
52 else
53 begin
54 if (cnt == N - 1 )
55 cnt <= 26 ' b0;
56 else
57 cnt <= cnt + 26 ' b1;
58 end
59 end
60 always @( posedge i_clk or negedge rst_n)
61 begin
62 if ( ! rst_n)
63 o_clk <= 0 ;
64 else
65 begin
66 if (cnt <= M)
67 o_clk <= 1 ;
68 else
69 o_clk <= 0 ;
70 end
71 end
72
73 endmodule
74
75 // seg7_lut
76 module seg7_lut (
77 output reg [ 6 : 0 ] oseg,
78 input [ 3 : 0 ] idig
79 );
80 always @ (idig)
81 begin
82 case (idig)
83 4 ' h1: oseg = 7 ' b1111001; // ---t---
84 4 ' h2: oseg = 7 ' b0100100; // | |
85 4 ' h3: oseg = 7 ' b0110000; // lt rt
86 4 ' h4: oseg = 7 ' b0011001; // | |
87 4 ' h5: oseg = 7 ' b0010010; // ---m---
88 4 ' h6: oseg = 7 ' b0000010; // | |
89 4 ' h7: oseg = 7 ' b1111000; // lb rb
90 4 ' h8: oseg = 7 ' b0000000; // | |
91 4 ' h9: oseg = 7 ' b0011000; // ---b---
92 4 ' ha: oseg = 7 ' b0001000;
93 4 ' hb: oseg = 7 ' b0000011;
94 4 ' hc: oseg = 7 ' b1000110;
95 4 ' hd: oseg = 7 ' b0100001;
96 4 ' he: oseg = 7 ' b0000110;
97 4 ' hf: oseg = 7 ' b0001110;
98 default : oseg = 7 ' b1000000;
99 endcase
100 end
101 endmodule

 

 

Part V 循环显示HELLO

 

在HEX7-HEX0上循环显示HELLO,如图8所示。

001

图8 8个7segment上循环显示HELLO

 

代码

 

top-level file
1 // top-level file
2 module hello(HEX7,HEX6,HEX5,HEX4,
3 HEX3,HEX2,HEX1,HEX0,
4 CLOCK_50,KEY);
5 input CLOCK_50;
6 input [ 0 : 0 ]KEY;
7 output [ 6 : 0 ]HEX7,HEX6,HEX5,HEX4,HEX3,HEX2,
8 HEX1,HEX0;
9
10 wire clk_1hz;
11 reg [ 3 : 0 ]cnt;
12
13 div u0(.o_clk(clk_1hz),
14 .rst_n(KEY),
15 .i_clk(CLOCK_50)
16 );
17
18 always @( posedge clk_1hz or negedge KEY)
19 begin
20 if ( ! KEY)
21 cnt <= 4 ' b0;
22 else
23 begin
24 if (cnt == 4 ' b0111)
25 cnt <= 4 ' b0;
26 else
27 cnt <= cnt + 1 ' b1;
28 end
29 end
30
31 seg7_h0 h0(.oseg(HEX0),
32 .idig(cnt)
33 );
34 seg7_h1 h1(.oseg(HEX1),
35 .idig(cnt)
36 );
37 seg7_h2 h2(.oseg(HEX2),
38 .idig(cnt)
39 );
40 seg7_h3 h3(.oseg(HEX3),
41 .idig(cnt)
42 );
43 seg7_h4 h4(.oseg(HEX4),
44 .idig(cnt)
45 );
46 seg7_h5 h5(.oseg(HEX5),
47 .idig(cnt)
48 );
49 seg7_h6 h6(.oseg(HEX6),
50 .idig(cnt)
51 );
52 seg7_h7 h7(.oseg(HEX7),
53 .idig(cnt)
54 );
55 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 + 26 ' 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

 

译码0
1 // seg7_lut
2 module seg7_h0
3 (
4 output reg [ 6 : 0 ] oseg,
5 input [ 3 : 0 ] idig
6 );
7 always @ (idig)
8 begin
9 case (idig)
10 4 ' h0: oseg = 7 ' b1000000; // O
11 // 4'h1: oseg = 7'b1111001;
12 // 4'h2: oseg = 7'b0100100;
13 // 4'h3: oseg = 7'b0110000;
14 4 ' h4: oseg = 7 ' b0001001; // H
15 4 ' h5: oseg = 7 ' b0000110; // E
16 4 ' h6: oseg = 7 ' b1000111; // L
17 4 ' h7: oseg = 7 ' b1000111; // L
18
19 default : oseg = 7 ' b1111111;
20 endcase
21 end
22 endmodule

 

译码1
1 // seg7_lut
2 module seg7_h1
3 (
4 output reg [ 6 : 0 ] oseg,
5 input [ 3 : 0 ] idig
6 );
7 always @ (idig)
8 begin
9 case (idig)
10 4 ' h1: oseg = 7 ' b1000000; // O
11 // 4'h4: oseg = 7'b1111001;
12 // 4'h2: oseg = 7'b0100100;
13 // 4'h3: oseg = 7'b0110000;
14 4 ' h5: oseg = 7 ' b0001001; // H
15 4 ' h6: oseg = 7 ' b0000110; // E
16 4 ' h7: oseg = 7 ' b1000111; // L
17 4 ' h0: oseg = 7 ' b1000111; // L
18
19 default : oseg = 7 ' b1111111;
20 endcase
21 end
22 endmodule

 

共8个译码模块(略6)

解法2

  1 module part5(CLOCK_50,HEX7,HEX6,HEX5,HEX4,HEX3,HEX2,HEX1,HEX0);

  2     input CLOCK_50;

  3     output reg [6:0] HEX7,HEX6,HEX5,HEX4,HEX3,HEX2,HEX1,HEX0;

  4     

  5     parameter blank=7'b1_111_111,

  6                 H=7'b0_001_001,

  7                 E=7'b0_000_110,

  8                 L=7'b1_000_111,

  9                 O=7'b1_000_000;

 10                 

 11     wire clk_1hz;

 12     wire [3:0] cnt;

 13     

 14     div u0(CLOCK_50,clk_1hz,1'b1);

 15     counter8 u1(clk_1hz,1'b1,cnt);

 16     

 17     always @(cnt)

 18     case(cnt)

 19         4'd0:begin

 20                 HEX7=blank;

 21                 HEX6=blank;

 22                 HEX5=blank;

 23                 HEX4=H;

 24                 HEX3=E;

 25                 HEX2=L;

 26                 HEX1=L;

 27                 HEX0=O;

 28             end

 29         4'd1:begin

 30                 HEX0=blank;

 31                 HEX7=blank;

 32                 HEX6=blank;

 33                 HEX5=H;

 34                 HEX4=E;

 35                 HEX3=L;

 36                 HEX2=L;

 37                 HEX1=O;

 38             end    

 39         4'd2:begin

 40                 HEX1=blank;

 41                 HEX0=blank;

 42                 HEX7=blank;

 43                 HEX6=H;

 44                 HEX5=E;

 45                 HEX4=L;

 46                 HEX3=L;

 47                 HEX2=O;

 48             end    

 49         4'd3:begin

 50                 HEX2=blank;

 51                 HEX1=blank;

 52                 HEX0=blank;

 53                 HEX7=H;

 54                 HEX6=E;

 55                 HEX5=L;

 56                 HEX4=L;

 57                 HEX3=O;

 58             end    

 59         4'd4:begin

 60                 HEX3=blank;

 61                 HEX2=blank;

 62                 HEX1=blank;

 63                 HEX0=H;

 64                 HEX7=E;

 65                 HEX6=L;

 66                 HEX5=L;

 67                 HEX4=O;

 68             end    

 69         4'd5:begin

 70                 HEX4=blank;

 71                 HEX3=blank;

 72                 HEX2=blank;

 73                 HEX1=H;

 74                 HEX0=E;

 75                 HEX7=L;

 76                 HEX6=L;

 77                 HEX5=O;

 78             end    

 79         4'd6:begin

 80                 HEX5=blank;

 81                 HEX4=blank;

 82                 HEX3=blank;

 83                 HEX2=H;

 84                 HEX1=E;

 85                 HEX0=L;

 86                 HEX7=L;

 87                 HEX6=O;

 88             end            

 89         4'd7:begin

 90                 HEX6=blank;

 91                 HEX5=blank;

 92                 HEX4=blank;

 93                 HEX3=H;

 94                 HEX2=E;

 95                 HEX1=L;

 96                 HEX0=L;

 97                 HEX7=O;

 98             end    

 99     endcase

100     

101 endmodule        

102                 

其实还可以利用字型码加1的方法。

Conclusion

 

Part1 有助于理解计数器的具体实现,Part4是Part5的基础,单个7segment循环显示操作成功,多个

自然不难。:)

 

Reference

 

《Using library modules in Verilog Designs 》

你可能感兴趣的:(Verilog)