您的位置:首页 > 其它

【黑金教程笔记之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,不用那么较真)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐