【黑金教程笔记之008】【建模篇】【Lab 07 数码管电路驱动】—笔记
2014-11-12 22:20
513 查看
实验七的目的是设计实现最大为99数字在2个数码管上。采用同步动态扫描。即行信号和列信号同步扫描。这里数码管是共阳极的。选择端口也是共阳极的。
模块:
/************************************* module name: number_mod_module.v function: generate ten-bit and one-bit number. by yf.x 2014-11-11 *************************************/ module number_mod_module( CLK, RST_n, Number_data, Ten_data, One_data ); input CLK; input RST_n; input [7:0] Number_data; output [3:0] Ten_data; output [3:0] One_data; /********************************/ reg [31:0]rTen; reg [31:0]rOne; always @(posedge CLK or negedge RST_n) if(!RST_n) begin rTen<=32'd0; rOne<=32'd0; end else begin rTen<=Number_data/10; rOne<=Number_data%10; end /***********************************/ assign Ten_data=rTen[3:0]; assign One_data=rOne[3:0]; /***********************************/ endmodule
/********************************************** module name:digital_tube_encode_module.v function: encode by yf.x 2014-11-11 **********************************************/ module digital_tube_encode_module( CLK, RST_n, Ten_data, One_data, Ten_dig_tube_data, One_dig_tube_data ); input CLK; input RST_n; input [3:0]Ten_data; input [3:0]One_data; output [7:0]Ten_dig_tube_data; output [7:0]One_dig_tube_data; /****************************************/ //common anode digital tube parameter _0=8'b1100_0000, _1=8'b1111_1001, _2=8'b1010_0100, _3=8'b1011_0000, _4=8'b1001_1001, _5=8'b1001_0010, _6=8'b1000_0010, _7=8'b1111_1000, _8=8'b1000_0000, _9=8'b1001_0000; /*******************************************/ reg [7:0]rTen_dig_tube_data; always @(posedge CLK or negedge RST_n) if(!RST_n) begin rTen_dig_tube_data<=8'b1111_1111; end else case(Ten_data) 4'd0:rTen_dig_tube_data<=_0; 4'd1:rTen_dig_tube_data<=_1; 4'd2:rTen_dig_tube_data<=_2; 4'd3:rTen_dig_tube_data<=_3; 4'd4:rTen_dig_tube_data<=_4; 4'd5:rTen_dig_tube_data<=_5; 4'd6:rTen_dig_tube_data<=_6; 4'd7:rTen_dig_tube_data<=_7; 4'd8:rTen_dig_tube_data<=_8; 4'd9:rTen_dig_tube_data<=_9; endcase /**************************************/ reg [7:0]rOne_dig_tube_data; always @(posedge CLK or negedge RST_n) if(!RST_n) begin rOne_dig_tube_data<=8'b1111_1111; end else case(One_data) 4'd0:rOne_dig_tube_data<=_0; 4'd1:rOne_dig_tube_data<=_1; 4'd2:rOne_dig_tube_data<=_2; 4'd3:rOne_dig_tube_data<=_3; 4'd4:rOne_dig_tube_data<=_4; 4'd5:rOne_dig_tube_data<=_5; 4'd6:rOne_dig_tube_data<=_6; 4'd7:rOne_dig_tube_data<=_7; 4'd8:rOne_dig_tube_data<=_8; 4'd9:rOne_dig_tube_data<=_9; endcase /********************************************/ assign Ten_dig_tube_data=rTen_dig_tube_data; assign One_dig_tube_data=rOne_dig_tube_data; /********************************************/ endmodule
/***************************************** module name: column_scan_module.v function: choose which digital tube enable. by yf.x 2014-11-11 *****************************************/ module column_scan_module( CLK, RST_n, Column_scan_sig ); input CLK; input RST_n; output [1:0]Column_scan_sig; /****************************************/ //50M*0.01-1=499_999 parameter T10ms=19'd499_999; /****************************************/ reg [18:0]count1; always @(posedge CLK or negedge RST_n) if(!RST_n) count1<=19'd0; else if(count1==T10ms) count1<=19'd0; else count1<=count1+1'b1; /****************************************/ reg [1:0] t; always @(posedge CLK or negedge RST_n) if(!RST_n) t<=2'd0; else if(t==2'd2) t<=2'd0; else if(count1==T10ms) t<=t+1'b1; /******************************************/ reg [1:0] rColumn_scan; always @(posedge CLK or negedge RST_n) if(!RST_n) rColumn_scan<=2'b10; else if(count1==T10ms) case(t) 2'd0:rColumn_scan<=2'b10; 2'd1:rColumn_scan<=2'b01; endcase /*******************************************/ assign Column_scan_sig=rColumn_scan; /*******************************************/ endmodule
/***************************************** module name: row_scan_module.v function: choose which number enable. by yf.x 2014-11-11 *****************************************/ module row_scan_module( CLK, RST_n, Ten_dig_tube_data, One_dig_tube_data, Row_scan_sig ); input CLK; input RST_n; input [7:0]Ten_dig_tube_data; input [7:0]One_dig_tube_data; output [7:0]Row_scan_sig; /****************************************/ //50M*0.01-1=499_999 parameter T10ms=19'd499_999; /****************************************/ reg [18:0]count1; always @(posedge CLK or negedge RST_n) if(!RST_n) count1<=19'd0; else if(count1==T10ms) count1<=19'd0; else count1<=count1+1'b1; /****************************************/ reg [1:0] t; always @(posedge CLK or negedge RST_n) if(!RST_n) t<=2'd0; else if(t==2'd2) t<=2'd0; else if(count1==T10ms) t<=t+1'b1; /******************************************/ reg [7:0] rRow_scan; always @(posedge CLK or negedge RST_n) if(!RST_n) rRow_scan<=8'd0; else if(count1==T10ms) case(t) 2'd0:rRow_scan<=Ten_dig_tube_data; 2'd1:rRow_scan<=One_dig_tube_data; endcase /*******************************************/ assign Row_scan_sig=rRow_scan; /*******************************************/ endmodule
/************************************************* module name:dig_tube_scan_module.v function: choose tube and number by yf.x 2014-11-11 *************************************************/ module dig_tube_scan_module( CLK, RST_n, Ten_dig_tube_data, One_dig_tube_data, Column_scan_sig, Row_scan_sig ); input CLK; input RST_n; input [7:0]Ten_dig_tube_data; input [7:0]One_dig_tube_data; output [1:0]Column_scan_sig; output [7:0]Row_scan_sig; /*****************************************/ column_scan_module u0( .CLK(CLK), .RST_n(RST_n), .Column_scan_sig(Column_scan_sig) ); row_scan_module u1( .CLK(CLK), .RST_n(RST_n), .Ten_dig_tube_data(Ten_dig_tube_data), .One_dig_tube_data(One_dig_tube_data), .Row_scan_sig(Row_scan_sig) ); /*******************************************/ endmodule
/*************************************** module name: lab07_top.v function: dirver digital tube show number pin assignments(for DE2-115): ---------------------------------- CLK-----------------------CLOCK_50 RST_n---------------------KEY[0] HEX1-0-----------HEX1-0 ---------------------------------- by yf.x 2014-11-11 ***************************************/ module lab07_top( CLK, RST_n, HEX1, HEX0 ); input CLK; input RST_n; output [6:0]HEX1; output [6:0]HEX0; wire [7:0]Number_data; wire [7:0]Row_scan_sig; wire [1:0]Column_scan_sig; reg [6:0] rHEX1; reg [6:0] rHEX0; /**************************************/ wire [3:0]Ten_data; wire [3:0]One_data; number_mod_module u0( .CLK(CLK), .RST_n(RST_n), .Number_data(Number_data), .Ten_data(Ten_data), .One_data(One_data) ); /***************************************/ wire [7:0]Ten_dig_tube_data; wire [7:0]One_dig_tube_data; digital_tube_encode_module u1( .CLK(CLK), .RST_n(RST_n), .Ten_data(Ten_data), .One_data(One_data), .Ten_dig_tube_data(Ten_dig_tube_data), .One_dig_tube_data(One_dig_tube_data) ); /***************************************/ dig_tube_scan_module u2( .CLK(CLK), .RST_n(RST_n), .Ten_dig_tube_data(Ten_dig_tube_data), .One_dig_tube_data(One_dig_tube_data), .Column_scan_sig(Column_scan_sig), .Row_scan_sig(Row_scan_sig) ); /*******************************************/ count100 u3( .CLK(CLK), .RST_n(RST_n), .Count_out(Number_data) ); /*******************************************/ always @(posedge CLK or negedge RST_n) if(!RST_n) begin rHEX1<=7'b111_1111; rHEX0<=7'b111_1111; end else case(Column_scan_sig) 2'b10:rHEX1<=Row_scan_sig; 2'b01:rHEX0<=Row_scan_sig; endcase /*******************************************/ assign HEX1=rHEX1; assign HEX0=rHEX0; /*******************************************/ endmodule
/********************************************************************** module name: count100.v function:count from 0 to 99, add 1 at each 100ms. by yf.x 2014-11-12 **********************************************************************/ module count100( CLK, RST_n, Count_out ); input CLK; input RST_n; output [8:0]Count_out; /****************************************/ //50M*0.1-1=4_999_999 parameter T100ms=26'd4_999_999; /****************************************/ reg [25:0]count1; always @(posedge CLK or negedge RST_n) if(!RST_n) count1<=26'd0; else if(count1==T100ms) count1<=26'd0; else count1<=count1+1'b1; /****************************************/ reg [7:0] Number_data; always @(posedge CLK or negedge RST_n) if(!RST_n) Number_data<=8'd0; else if(Number_data==8'd100) Number_data<=8'd0; else if(count1==T100ms) Number_data<=Number_data+1'b1; /****************************************/ assign Count_out=Number_data; /****************************************/ endmodule
模块说明:
(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,不用那么较真)。
相关文章推荐
- 【黑金教程笔记之003】【建模篇】【Lab 02 闪耀灯和流水灯】—笔记
- 【黑金教程笔记之007】【建模篇】【Lab 06 SOS信号之二】—笔记
- Verilog HDL那些事_建模篇笔记(实验七:数码管电路驱动)
- 【黑金教程笔记之002】【建模篇】【Lab 01 永远的流水灯】—笔记&勘误
- 【黑金教程笔记之006】【建模篇】【Lab 05 SOS信号之一】—笔记
- 【黑金教程笔记之005】【建模篇】【Lab 04 消抖模块之二】—笔记
- 【黑金教程笔记之004】【建模篇】【Lab 03 消抖模块之一】—笔记
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验六:数码管模块
- 【黑金教程笔记之003】【建模篇】akuei2的Verilog hdl心路
- 【连载】【FPGA黑金开发板】Verilog HDL那些事儿--数码管电路驱动(八)
- 【连载】【FPGA黑金开发板】Verilog HDL那些事儿--数码管电路驱动(八)
- Verilog 初学笔记--顺序操作 和 并行操作的一点思考(参考黑金教程:Verilog HDL那些事 建模篇)
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二:按键模块① - 消抖
- 【黑金教程笔记之001】veriloghdl 扫盲文—笔记&勘误
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验三:按键模块② — 点击与长点击
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验八:PS/2模块② — 键盘与组合键
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验九:PS/2模块③ — 键盘与多组合键
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十一:PS/2模块⑤ — 扩展鼠标
- 【黑金视频连载】FPGA NIOSII视频教程(07)--PIO寄存器问题解析
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十:PS/2模块④ — 普通鼠标