实验七的目的是设计实现最大为99数字在2个数码管上。采用同步动态扫描。即行信号和列信号同步扫描。这里数码管是共阳极的。选择端口也是共阳极的。
模块:
1 /************************************* 2 module name: number_mod_module.v 3 function: generate ten-bit and one-bit 4 number. 5 6 by yf.x 7 2014-11-11 8 9 *************************************/ 10 11 module number_mod_module( 12 CLK, 13 RST_n, 14 Number_data, 15 Ten_data, 16 One_data 17 ); 18 19 input CLK; 20 input RST_n; 21 input [7:0] Number_data; 22 output [3:0] Ten_data; 23 output [3:0] One_data; 24 25 /********************************/ 26 27 reg [31:0]rTen; 28 reg [31:0]rOne; 29 30 always @(posedge CLK or negedge RST_n) 31 if(!RST_n) 32 begin 33 rTen<=32‘d0; 34 rOne<=32‘d0; 35 end 36 else 37 begin 38 rTen<=Number_data/10; 39 rOne<=Number_data%10; 40 end 41 42 /***********************************/ 43 44 assign Ten_data=rTen[3:0]; 45 assign One_data=rOne[3:0]; 46 47 /***********************************/ 48 49 endmodule 50
1 /********************************************** 2 module name:digital_tube_encode_module.v 3 function: encode 4 5 by yf.x 6 2014-11-11 7 8 **********************************************/ 9 10 module digital_tube_encode_module( 11 CLK, 12 RST_n, 13 Ten_data, 14 One_data, 15 Ten_dig_tube_data, 16 One_dig_tube_data 17 ); 18 19 input CLK; 20 input RST_n; 21 input [3:0]Ten_data; 22 input [3:0]One_data; 23 output [7:0]Ten_dig_tube_data; 24 output [7:0]One_dig_tube_data; 25 26 /****************************************/ 27 //common anode digital tube 28 parameter _0=8‘b1100_0000, 29 _1=8‘b1111_1001, 30 _2=8‘b1010_0100, 31 _3=8‘b1011_0000, 32 _4=8‘b1001_1001, 33 _5=8‘b1001_0010, 34 _6=8‘b1000_0010, 35 _7=8‘b1111_1000, 36 _8=8‘b1000_0000, 37 _9=8‘b1001_0000; 38 39 /*******************************************/ 40 41 reg [7:0]rTen_dig_tube_data; 42 43 always @(posedge CLK or negedge RST_n) 44 if(!RST_n) 45 begin 46 rTen_dig_tube_data<=8‘b1111_1111; 47 end 48 else 49 case(Ten_data) 50 4‘d0:rTen_dig_tube_data<=_0; 51 4‘d1:rTen_dig_tube_data<=_1; 52 4‘d2:rTen_dig_tube_data<=_2; 53 4‘d3:rTen_dig_tube_data<=_3; 54 4‘d4:rTen_dig_tube_data<=_4; 55 4‘d5:rTen_dig_tube_data<=_5; 56 4‘d6:rTen_dig_tube_data<=_6; 57 4‘d7:rTen_dig_tube_data<=_7; 58 4‘d8:rTen_dig_tube_data<=_8; 59 4‘d9:rTen_dig_tube_data<=_9; 60 endcase 61 62 /**************************************/ 63 64 reg [7:0]rOne_dig_tube_data; 65 66 always @(posedge CLK or negedge RST_n) 67 if(!RST_n) 68 begin 69 rOne_dig_tube_data<=8‘b1111_1111; 70 end 71 else 72 case(One_data) 73 4‘d0:rOne_dig_tube_data<=_0; 74 4‘d1:rOne_dig_tube_data<=_1; 75 4‘d2:rOne_dig_tube_data<=_2; 76 4‘d3:rOne_dig_tube_data<=_3; 77 4‘d4:rOne_dig_tube_data<=_4; 78 4‘d5:rOne_dig_tube_data<=_5; 79 4‘d6:rOne_dig_tube_data<=_6; 80 4‘d7:rOne_dig_tube_data<=_7; 81 4‘d8:rOne_dig_tube_data<=_8; 82 4‘d9:rOne_dig_tube_data<=_9; 83 endcase 84 85 /********************************************/ 86 87 assign Ten_dig_tube_data=rTen_dig_tube_data; 88 assign One_dig_tube_data=rOne_dig_tube_data; 89 90 /********************************************/ 91 92 endmodule 93 94 95 96
1 /***************************************** 2 module name: column_scan_module.v 3 function: choose which digital tube enable. 4 5 by yf.x 6 2014-11-11 7 8 *****************************************/ 9 10 module column_scan_module( 11 CLK, 12 RST_n, 13 Column_scan_sig 14 ); 15 16 input CLK; 17 input RST_n; 18 output [1:0]Column_scan_sig; 19 20 /****************************************/ 21 //50M*0.01-1=499_999 22 parameter T10ms=19‘d499_999; 23 24 /****************************************/ 25 26 reg [18:0]count1; 27 28 always @(posedge CLK or negedge RST_n) 29 if(!RST_n) 30 count1<=19‘d0; 31 else if(count1==T10ms) 32 count1<=19‘d0; 33 else 34 count1<=count1+1‘b1; 35 36 /****************************************/ 37 38 reg [1:0] t; 39 40 always @(posedge CLK or negedge RST_n) 41 if(!RST_n) 42 t<=2‘d0; 43 else if(t==2‘d2) 44 t<=2‘d0; 45 else if(count1==T10ms) 46 t<=t+1‘b1; 47 48 /******************************************/ 49 50 reg [1:0] rColumn_scan; 51 52 always @(posedge CLK or negedge RST_n) 53 if(!RST_n) 54 rColumn_scan<=2‘b10; 55 else if(count1==T10ms) 56 case(t) 57 2‘d0:rColumn_scan<=2‘b10; 58 2‘d1:rColumn_scan<=2‘b01; 59 endcase 60 61 /*******************************************/ 62 63 assign Column_scan_sig=rColumn_scan; 64 65 /*******************************************/ 66 67 endmodule 68
1 /***************************************** 2 module name: row_scan_module.v 3 function: choose which number enable. 4 5 by yf.x 6 2014-11-11 7 8 *****************************************/ 9 10 module row_scan_module( 11 CLK, 12 RST_n, 13 Ten_dig_tube_data, 14 One_dig_tube_data, 15 Row_scan_sig 16 ); 17 18 input CLK; 19 input RST_n; 20 input [7:0]Ten_dig_tube_data; 21 input [7:0]One_dig_tube_data; 22 output [7:0]Row_scan_sig; 23 24 /****************************************/ 25 //50M*0.01-1=499_999 26 parameter T10ms=19‘d499_999; 27 28 /****************************************/ 29 30 reg [18:0]count1; 31 32 always @(posedge CLK or negedge RST_n) 33 if(!RST_n) 34 count1<=19‘d0; 35 else if(count1==T10ms) 36 count1<=19‘d0; 37 else 38 count1<=count1+1‘b1; 39 40 /****************************************/ 41 42 reg [1:0] t; 43 44 always @(posedge CLK or negedge RST_n) 45 if(!RST_n) 46 t<=2‘d0; 47 else if(t==2‘d2) 48 t<=2‘d0; 49 else if(count1==T10ms) 50 t<=t+1‘b1; 51 52 /******************************************/ 53 54 reg [7:0] rRow_scan; 55 56 always @(posedge CLK or negedge RST_n) 57 if(!RST_n) 58 rRow_scan<=8‘d0; 59 else if(count1==T10ms) 60 case(t) 61 2‘d0:rRow_scan<=Ten_dig_tube_data; 62 2‘d1:rRow_scan<=One_dig_tube_data; 63 endcase 64 65 /*******************************************/ 66 67 assign Row_scan_sig=rRow_scan; 68 69 /*******************************************/ 70 71 endmodule 72
1 /************************************************* 2 module name:dig_tube_scan_module.v 3 function: choose tube and number 4 5 by yf.x 6 2014-11-11 7 8 *************************************************/ 9 10 module dig_tube_scan_module( 11 CLK, 12 RST_n, 13 Ten_dig_tube_data, 14 One_dig_tube_data, 15 Column_scan_sig, 16 Row_scan_sig 17 ); 18 19 input CLK; 20 input RST_n; 21 input [7:0]Ten_dig_tube_data; 22 input [7:0]One_dig_tube_data; 23 output [1:0]Column_scan_sig; 24 output [7:0]Row_scan_sig; 25 26 /*****************************************/ 27 28 column_scan_module u0( 29 .CLK(CLK), 30 .RST_n(RST_n), 31 .Column_scan_sig(Column_scan_sig) 32 ); 33 34 row_scan_module u1( 35 .CLK(CLK), 36 .RST_n(RST_n), 37 .Ten_dig_tube_data(Ten_dig_tube_data), 38 .One_dig_tube_data(One_dig_tube_data), 39 .Row_scan_sig(Row_scan_sig) 40 ); 41 42 /*******************************************/ 43 44 endmodule
1 /*************************************** 2 module name: lab07_top.v 3 function: dirver digital tube show number 4 pin assignments(for DE2-115): 5 ---------------------------------- 6 CLK-----------------------CLOCK_50 7 RST_n---------------------KEY[0] 8 HEX1-0-----------HEX1-0 9 ---------------------------------- 10 11 by yf.x 12 2014-11-11 13 14 ***************************************/ 15 module lab07_top( 16 CLK, 17 RST_n, 18 HEX1, 19 HEX0 20 ); 21 22 input CLK; 23 input RST_n; 24 output [6:0]HEX1; 25 output [6:0]HEX0; 26 27 wire [7:0]Number_data; 28 wire [7:0]Row_scan_sig; 29 wire [1:0]Column_scan_sig; 30 reg [6:0] rHEX1; 31 reg [6:0] rHEX0; 32 33 /**************************************/ 34 35 wire [3:0]Ten_data; 36 wire [3:0]One_data; 37 38 number_mod_module u0( 39 .CLK(CLK), 40 .RST_n(RST_n), 41 .Number_data(Number_data), 42 .Ten_data(Ten_data), 43 .One_data(One_data) 44 ); 45 46 /***************************************/ 47 48 wire [7:0]Ten_dig_tube_data; 49 wire [7:0]One_dig_tube_data; 50 51 digital_tube_encode_module u1( 52 .CLK(CLK), 53 .RST_n(RST_n), 54 .Ten_data(Ten_data), 55 .One_data(One_data), 56 .Ten_dig_tube_data(Ten_dig_tube_data), 57 .One_dig_tube_data(One_dig_tube_data) 58 ); 59 60 /***************************************/ 61 62 dig_tube_scan_module u2( 63 .CLK(CLK), 64 .RST_n(RST_n), 65 .Ten_dig_tube_data(Ten_dig_tube_data), 66 .One_dig_tube_data(One_dig_tube_data), 67 .Column_scan_sig(Column_scan_sig), 68 .Row_scan_sig(Row_scan_sig) 69 ); 70 71 /*******************************************/ 72 73 count100 u3( 74 .CLK(CLK), 75 .RST_n(RST_n), 76 .Count_out(Number_data) 77 ); 78 79 /*******************************************/ 80 81 always @(posedge CLK or negedge RST_n) 82 if(!RST_n) 83 begin 84 rHEX1<=7‘b111_1111; 85 rHEX0<=7‘b111_1111; 86 end 87 else 88 case(Column_scan_sig) 89 2‘b10:rHEX1<=Row_scan_sig; 90 2‘b01:rHEX0<=Row_scan_sig; 91 endcase 92 93 /*******************************************/ 94 95 assign HEX1=rHEX1; 96 assign HEX0=rHEX0; 97 98 /*******************************************/ 99 100 101 102 endmodule
1 /********************************************************************** 2 module name: count100.v 3 function:count from 0 to 99, add 1 at each 100ms. 4 5 by yf.x 6 2014-11-12 7 8 **********************************************************************/ 9 10 module count100( 11 CLK, 12 RST_n, 13 Count_out 14 ); 15 16 input CLK; 17 input RST_n; 18 output [8:0]Count_out; 19 20 /****************************************/ 21 //50M*0.1-1=4_999_999 22 parameter T100ms=26‘d4_999_999; 23 24 /****************************************/ 25 26 reg [25:0]count1; 27 28 always @(posedge CLK or negedge RST_n) 29 if(!RST_n) 30 count1<=26‘d0; 31 else if(count1==T100ms) 32 count1<=26‘d0; 33 else 34 count1<=count1+1‘b1; 35 36 /****************************************/ 37 38 reg [7:0] Number_data; 39 40 always @(posedge CLK or negedge RST_n) 41 if(!RST_n) 42 Number_data<=8‘d0; 43 else if(Number_data==8‘d100) 44 Number_data<=8‘d0; 45 else if(count1==T100ms) 46 Number_data<=Number_data+1‘b1; 47 48 /****************************************/ 49 50 assign Count_out=Number_data; 51 52 /****************************************/ 53 54 endmodule 55
模块说明:
(1) 取位模块,RTL视图如下
(2) 加码模块,简单的译码,没啥好说的。参数的应用,更直观些。
(3) 扫描模块,整个设计较难之处,数码管在那里,数字也在那里,在某一时刻准确的选择数码管和数字这两种不同的东东就需要扫描2次,所谓行扫描,列扫描,不过是文字上的名称罢了,设计的思想就是同一时刻,不同东东要匹配起来,有几种东东,就扫描几次。所以名称完全可以自己随便创造。
Qestion:
(1) 行扫描信号和列扫描信号的作用?
列扫描信号用来选择当前用哪个数码管来显示,每个数码管保持10ms;行扫描信号用来决定显示什么(十位上的数字还是个位上的数字),也是10ms的间隔。这样,两个数码管就可以准确对应,交替显示。
(2) 三个模块的功能:十位取码模块是把一个数的个位和十位上的数字分别取出来;SMG加码模块是把4-bit的数字译码成数码管上要显示的数字码;扫描模块决定哪个数码管显示和显示什么。
(3) 数字取位模块里声明32位的寄存器是因为在9.0之后的版本Quartus II里除法器和求余器默认是32位输出。经过编译后,会自动优化最适合的位宽。
(4) 部分代码说明:核心模块如上述框图显示,取位,译码,扫描。但要使整个设计落地到DE2-115上,这块神板的数码管好像是没有使用扫描的引脚,即不能直接像大多数数码管设计里扫描显示。它那样设计的原因可能是要更直接更傻瓜化吧:),所以在代码的顶层模块里,“画蛇添足”的用一个case选择哪个数码管显示,有点破坏低级建模,模块功能单一,搭积木的感觉。先这样凑合吧。另外,要显示的数字本身,用DE2-115上的拨动开关组合可以,更简单的就是用计数器直接生成,所以,干脆写了一个每隔100ms增1的100进制的计数器(其实是模101,不用那么较真)。