生产实习报告班级:通信13-2班姓名:闫振宇学号:成绩:电子与信息工程学院信息与通信工程系基于verilog数字秒表的设计实现1. 概述硬件描述语言HDL ( HardwareDescription Langyage) 是一种用形式化方法来描述数字电路和系统的语言。
数字电路系统的设计这里用这种语言可以从上层倒下层逐层描述自设计思想用一系列分层的模块来表示极其复杂的数字系统,然后用EDA 工具逐层验证,把其中需要为具体物理电路的模块组合由自动综合工具转换到门级电路网表。
Verilog HDL 是一种硬件描述语言,用于从算法级、门级到开关级的多种抽象设计层次的数字系统建模。
被建模的数字系统对象的复杂性可以介于简单的门和完整的电子数字系统之间。
数字系统能够按层次描述,并可在相同描述中显式地进行时序建模。
使用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,以及设计的要求及目的,可以将Verilog HDL语言设计的秒表计时程序分为四大模块:1)按键输入缓存,按键消抖模块;2)分频产生100HZ的时钟信号模块;3)数码管动态扫描显示驱动模块;4)计时处理部模块。
5.软件设计按键输入缓存,按键消抖模块常在按键较少时可用硬件方法消除抖动,一般采用RS触发器作为常用的消抖电路,如果按键较多时,常用软件消除抖动。
在EDA的设计应用中,软件消抖的方法即可使用RS触发器进行消抖,也可通过检测按键按下的时间进行消抖。
按键输入缓存,按键消抖程序:always@(posedge count[16])beginkey_inner<=key;endalways@(posedge key_inner[0])beginkey_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@(posedge clk) begin if(count==249999) begin clk_100hz<=~clk_100hz; count<=0;endelsecount<=count+1;end分频原理图,如图5-1所示。
图5-1 分频原理图分频原理:由于开发板的输入频率为50MHZ 的时钟信号,说明1s 产生7510⨯个时钟信号。
每个时钟信号持续的时间为71510⨯s ,由于秒表计时器的最小单位为,所以要将50MHZ 的时钟信号进行5510⨯分频,得到100HZ 的时钟信号,即。
数码管动态扫描显示驱动模块数码管动态扫描显示驱动程序:always@(posedge count[15])begincount3b=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;endcasesel=count3b;endalways@(dis_dat)begincase(dis_dat)0 : seg = 8'b1100_0000;erilog秒表设计.2012:15:17.[2]大彬哥.基于Verilog HDL的数字计时器的设计.2013:11.附件:module led_on(input[1:0]key, //输入信号input clk, //输入频率为50MHZ的时钟output reg [2:0]sel, //数码管位选output reg [7:0]seg, //数码管段选output en //3-8译码器使能);reg[2:0]count3b;reg[3:0]dis_dat; //定义显示数据寄存器reg[18:0]count; //定义计数寄存器reg[23:0]hour; //定义现在时刻寄存器reg clk_100hz; //50MHZ的时钟信号500000分频,得到100HZ的时钟信号reg key_flag; //启动/暂停的切换标志reg[1:0]key_inner;assign en=0;//(1)按键输入缓存,按键消抖设置always@(posedge count[16])//在内,扫描2的2次方,可以检测到4次高电平beginkey_inner<=key;endalways@(posedge key_inner[0])beginkey_flag=~key_flag;end//(2)秒信号产生部分,产生100HZ的时钟信号always@(posedge clk)beginif(count==249999)beginclk_100hz<=~clk_100hz;count<=0;endelsecount<=count+1;end//(3)数码管动态扫描显示部分always@(posedge count[15]) //时序逻辑,由于有6个数码管,则在一秒内扫描2的6次方begincount3b=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;endcasesel=count3b;endalways@(dis_dat)begincase(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;endcaseend//(4)计时处理部分always@(posedge clk_100hz) //计时处理beginif(~key_inner[1]&&key_flag==1) //判断是否复位键,beginhour=24'h0;endelse if(!key_flag)beginhour[3:0]=hour[3:0]+1;if(hour[3:0]==4'ha)beginhour[3:0]=4'h0;hour[7:4]=hour[7:4]+1;if(hour[7:4]==4'ha)beginhour[7:4]=4'h0;hour[11:8]=hour[11:8]+1;if(hour[11:8]==4'ha)beginhour[11:8]=4'h0;hour[15:12]=hour[15:12]+1;if(hour[15:12]==4'h6)beginhour[15:12]=4'h0;hour[19:16]=hour[19:16]+1;if(hour[19:16]==4'ha)beginhour[19:16]=4'h0;hour[23:20]=hour[23:20]+1;endif(hour[23:20]==4'h6)hour[23:20]=4'h0;endendendendend end endmodule。