基于verilog数字秒表的设计实现.docx
《基于verilog数字秒表的设计实现.docx》由会员分享,可在线阅读,更多相关《基于verilog数字秒表的设计实现.docx(10页珍藏版)》请在冰点文库上搜索。
基于verilog数字秒表的设计实现
生产实习报告
班级:
通信13-2班
姓名:
闫振宇
学号:
成绩:
电子与信息工程学院
信息与通信工程系
基于verilog数字秒表的设计实现
1.概述
硬件描述语言HDL(HardwareDescriptionLangyage)是一种用形式化方法来描述数字电路和系统的语言。
数字电路系统的设计这里用这种语言可以从上层倒下层逐层描述自设计思想用一系列分层的模块来表示极其复杂的数字系统,然后用EDA工具逐层验证,把其中需要为具体物理电路的模块组合由自动综合工具转换到门级电路网表。
VerilogHDL是一种硬件描述语言,用于从算法级、门级到开关级的多种抽象设计层次的数字系统建模。
被建模的数字系统对象的复杂性可以介于简单的门和完整的电子数字系统之间。
数字系统能够按层次描述,并可在相同描述中显式地进行时序建模。
使用VERILOG进行系统设计时采用的是从顶至下的设计,自顶向下的设计是从系统机开始巴西同划分为若干个基本单元,然后再把每个单元划分为下一层的基本单元,这样下去直到可以直接用EDA元件库中的基本元件来实现为止。
2.设计目的及要求
a.有源晶振频率:
50MHZ;
b.测试计时范围:
00’00”00~59’59”99,显示的最长时间为59分59秒;
c.数字秒表的计时精度是10ms;
d.显示工作方式:
六位BCD七段数码管显示读数,两个按钮开关(一个按钮使秒表复位,另一个按钮控制秒表的启动/暂停)。
3.设计原理
秒表的逻辑结构较简单,它主要由四进制计数器、十六进制计数器、分频器、数据选择器、和显示译码器等组成。
在整个秒表中最关键的是如何获得一个精确的100HZ计时脉冲,除此之外,整个秒表还需有一个启动信号和一个清零信号,以便秒表能随意停止、启动以及清零复位。
秒表有共有6个输出显示,其中6个显示输出数据,分别为百分之一秒、十分之一秒、秒、十秒、分、十分,所以共有6个计数器与之相对应;6个计数器的输出全都为BCD码输出,这样便与同显示译码器连接。
利用一块芯片完成除时钟源,按键和显示器之外的所有数字电路功能。
所有数字逻辑功能都在CPLD器件上用Verilog语言实现。
这样设计具有体积小,设计周期短,调试方便,故障率地和修改升级容易等特点。
本设计采用依次采用以下设计方法:
1)按键输入缓存,键盘消抖设计;
2)分频产生秒信号,产生100HZ的时钟信号设计;
3)数码管动态扫描显示设计;
4)3-8译码器显示(译码)设计;
5)流水线式计数方法设计。
4.设计原理框图
秒表计时器设计原理框图,如图4-1所示。
图4-1秒表计时器设计原理框图
根据设计原理框图4-1,以及设计的要求及目的,可以将VerilogHDL语言设计的秒表计时程序分为四大模块:
1)按键输入缓存,按键消抖模块;
2)分频产生100HZ的时钟信号模块;
3)数码管动态扫描显示驱动模块;
4)计时处理部模块。
5.软件设计
按键输入缓存,按键消抖模块
常在按键较少时可用硬件方法消除抖动,一般采用RS触发器作为常用的消抖电路,如果按键较多时,常用软件消除抖动。
在EDA的设计应用中,软件消抖的方法即可使用RS触发器进行消抖,也可通过检测按键按下的时间进行消抖。
按键输入缓存,按键消抖程序:
always@(posedgecount[16])
begin
key_inner<=key;
end
always@(posedgekey_inner[0])
begin
key_flag=~key_flag;
end
键盘消抖工作原理:
设置输入信号key[1:
0],设置一个模值为4的控制计数器key_inner,判断计数寄存器count的第16位的上升沿,检测到key_inner为高电平。
由于计数寄存器的位数为18位。
则说明在内可以检测到4次高电平。
在人工按键key=‘1’时,key_inner为‘1’,如连续4次检测到高电平则key_inner一直为‘1’。
4次以上检测到高电平key_inner依旧为‘1’,也一直输出高电平。
这就确保了当按键信号持续高电平以上按键信号才有效。
抖动期间的高电平持续时间不足以输出高电平。
如没有连续4次以上检测到高电平,则key_inner为‘0’。
再判断key_inner的上升沿(按键按下为下降沿,弹起为上升沿),每当key_inner[0]出现一次上升沿(按键按下并弹起),key_flag将取反一次(设置key_flag的初值为‘0’)。
分频产生100HZ的时钟信号模块
分频产生100HZ的时钟信号程序:
always@(posedgeclk)
begin
if(count==249999)
begin
clk_100hz<=~clk_100hz;
count<=0;
end
else
count<=count+1;
end
分频原理图,如图5-1所示。
图5-1分频原理图
分频原理:
由于开发板的输入频率为50MHZ的时钟信号,说明1s产生
个时钟信号。
每个时钟信号持续的时间为
s,由于秒表计时器的最小单位为,所以要将50MHZ的时钟信号进行
分频,得到100HZ的时钟信号,即。
数码管动态扫描显示驱动模块
数码管动态扫描显示驱动程序:
always@(posedgecount[15])
begin
count3b=count3b+1;
case(count3b)
3'd5:
dis_dat=hour[3:
0];
3'd4:
dis_dat=hour[7:
4];
3'd3:
dis_dat=hour[11:
8];
3'd2:
dis_dat=hour[15:
12];
3'd1:
dis_dat=hour[19:
16];
3'd0:
dis_dat=hour[23:
20];
default:
dis_dat=4'bxxxx;
endcase
sel=count3b;
end
always@(dis_dat)
begin
case(dis_dat)
0:
seg=8'b1100_0000;
erilog秒表设计.2012:
15
17.
[2]大彬哥.基于VerilogHDL的数字计时器的设计.2013:
11.
附件:
moduleled_on
(
input[1:
0]key,//输入信号
inputclk,//输入频率为50MHZ的时钟
outputreg[2:
0]sel,//数码管位选
outputreg[7:
0]seg,//数码管段选
outputen//3-8译码器使能
);
reg[2:
0]count3b;
reg[3:
0]dis_dat;//定义显示数据寄存器
reg[18:
0]count;//定义计数寄存器
reg[23:
0]hour;//定义现在时刻寄存器
regclk_100hz;//50MHZ的时钟信号500000分频,得到100HZ的时钟信号
regkey_flag;//启动/暂停的切换标志
reg[1:
0]key_inner;
assignen=0;
//
(1)按键输入缓存,按键消抖设置
always@(posedgecount[16])//在内,扫描2的2次方,可以检测到4次高电平
begin
key_inner<=key;
end
always@(posedgekey_inner[0])
begin
key_flag=~key_flag;
end
//
(2)秒信号产生部分,产生100HZ的时钟信号
always@(posedgeclk)
begin
if(count==249999)
begin
clk_100hz<=~clk_100hz;
count<=0;
end
else
count<=count+1;
end
//(3)数码管动态扫描显示部分
always@(posedgecount[15])//时序逻辑,由于有6个数码管,则在一秒内扫描2的6次方
begin
count3b=count3b+1;
case(count3b)
3'd5:
dis_dat=hour[3:
0];
3'd4:
dis_dat=hour[7:
4];
3'd3:
dis_dat=hour[11:
8];
3'd2:
dis_dat=hour[15:
12];
3'd1:
dis_dat=hour[19:
16];
3'd0:
dis_dat=hour[23:
20];
default:
dis_dat=4'bxxxx;
endcase
sel=count3b;
end
always@(dis_dat)
begin
case(dis_dat)
0:
seg=8'b1100_0000;//显示“0”
1:
seg=8'b1111_1001;//显示“1”
2:
seg=8'b1010_0100;//显示“2”
3:
seg=8'b1011_0000;//显示“3”
4:
seg=8'b1001_1001;//显示“4”
5:
seg=8'b1001_0010;//显示“5”
6:
seg=8'b1000_0010;//显示“6”
7:
seg=8'b1111_1000;//显示“7”
8:
seg=8'b1000_0000;//显示“8”
9:
seg=8'b1001_0000;//显示“9”
default:
seg=8'bxxxxxxxx;
endcase
end
//(4)计时处理部分
always@(posedgeclk_100hz)//计时处理
begin
if(~key_inner[1]&&key_flag==1)//判断是否复位键,
begin
hour=24'h0;
end
elseif(!
key_flag)
begin
hour[3:
0]=hour[3:
0]+1;
if(hour[3:
0]==4'ha)
begin
hour[3:
0]=4'h0;
hour[7:
4]=hour[7:
4]+1;
if(hour[7:
4]==4'ha)
begin
hour[7:
4]=4'h0;
hour[11:
8]=hour[11:
8]+1;
if(hour[11:
8]==4'ha)
begin
hour[11:
8]=4'h0;
hour[15:
12]=hour[15:
12]+1;
if(hour[15:
12]==4'h6)
begin
hour[15:
12]=4'h0;
hour[19:
16]=hour[19:
16]+1;
if(hour[19:
16]==4'ha)
begin
hour[19:
16]=4'h0;
hour[23:
20]=hour[23:
20]+1;
end
if(hour[23:
20]==4'h6)
hour[23:
20]=4'h0;
end
end
end
end
end
end
endmodule