基于FPGA的Verilog HDL数字钟设计
专业班级 姓 名 学 号
一、实验目的
1.掌握可编程逻辑器件的应用开发技术 ——设计输入、编译、仿真和器件编程; 2.熟悉一种EDA软件使用; 3.掌握Verilog设计方法;
4.掌握分模块分层次的设计方法;
5.用Verilog完成一个多功能数字钟设计; 6.学会FPGA的仿真。
二、实验要求
? 功能要求:
利用实验板设计实现一个能显示时分秒的多功能电子钟,基本功能:
1) 准确计时,以数字形式显示时、分、秒,可通过按键选择当前显示时间围模式; 2) 计时时间围 00:00:00-23:59:59 3) 可实现校正时间功能;
4) 可通过实现时钟复位功能:00:00:00 扩展功能:
5) 定时报:时间自定(不要求改变),闹1分钟(1kHz)---利用板上LED或外接电路实
现。
6) 仿广播电台正点报时:XX:59:[51,53,55,57(500Hz);59(1kHz)] ---用板上LED或
外接
7) 报整点时数:XX:00:[00.5-XX.5](1kHz),自动、手动---用板上LED或外接 8) 手动输入校时; 9) 手动输入定时闹钟; 10) 万年历; 11) 其他扩展功能; ? 设计步骤与要求:
1) 计算并说明采用Basys2实验板时钟50MHz实现系统功能的基本原理。
2) 在Xilinx ISE13.1 软件中,利用层次化方法,设计实现模一百计数及显示的电
路系统,设计模块间的连接调用关系,编写并输入所设计的源程序文件。 3) 对源程序进行编译及仿真分析(注意合理设置,以便能够在验证逻辑的基础上尽快
得出仿真结果)。
4) 输入管脚约束文件,对设计项目进行编译与逻辑综合,生成下载所需.bit文件。 5) 在Basys2实验板上下载所生成的.bit文件,观察验证所设计的电路功能。
三、实验设计
功能说明:实现时钟,时间校时,闹铃定时,秒表计时等功能
1. 时钟功能:完成分钟/小时的正确计数并显示;秒的显示用LED灯的闪烁做指示;
时钟利用4位数码管显示时分;
2. 闹钟定时:实现定时提醒及定时报时,利用LED灯代替扬声器发出报时声音; 3. 时钟校时:当认为时钟不准确时,可以分别对分钟和小时位的值进行调整; 4. 秒表功能:利用4个数码管完成秒表显示: 可以实现清零、暂停并记录时间等功能。
秒表利用4位数码管计数;
方案说明:本次设计由时钟模块和译码模块组成。时钟模块中50MHz的系统时钟clk分频产生一个1Hz的使能控制信号enable,并以此产生1s的脉冲second_en以实现每秒计时,控制各个模式下的计数显示。
由模式控制信号选择当前数码管显示哪个状态:
mode=00,时钟常规显示状态, mode=01,闹铃定时状态, mode=10,时钟校时状态, mode=11,秒表计时状态;
时钟:利用count,smin0,smin1,shour0,shour1的计数来实现,具体情况见程序; 校时:当turn=1时,调整分位smin1、smin0;当turn=0时,调整小时位shour1、shour0; 闹铃:当turn=1时,调整分位amin1、amin0;当turn=0时,调整小时位ahour1、ahour0; 秒表:当pause=0时,开始计时;当pause=1时,暂停。
四、实验代码
时钟模块
module clock(clk, clr, pause, turn, mode, sec, min1, min0, hour1, hour0, alert, LD_alert ); input clk; //时钟信号(50MHz)
input clr; //清零键 input pause; //秒表暂停键 input turn; //调整分还是小时位的控制 input [1:0]mode; //决定时钟显示功能状态 output sec; //接发光二极管 output [3:0]min1; //用于输出接数码管4 output [3:0]min0; //用于输出接数码管3 output [3:0]hour1; //用于输出接数码管2 output [3:0]hour0; //用于输出接数码管1 output alert; //接发光二极管,代替蜂鸣器 output LD_alert; //当闹铃设定后,发光二极管显示 wire sec; //秒位显示 wire LD_alert; //用于闹铃存在时的提醒显示 //wire clk1; //时钟1s //wire clk2; //时钟100ms,用于秒表最小计时单位 //wire clr1; reg [3:0]min1; //常规显示 reg [3:0]min0; //常规显示 reg [3:0]hour1; //常规显示 reg [3:0]hour0; //常规显示 reg [3:0]smin1; //校时 reg [3:0]smin0; //校时 reg [3:0]shour1; //校时 reg [3:0]shour0; //校时 reg [3:0]amin1; //闹铃 reg [3:0]amin0; //闹铃 reg [3:0]ahour1; //闹铃 reg [3:0]ahour0; //闹铃 reg [3:0]mmin1; //秒表 reg [3:0]mmin0; //秒表 reg [3:0]mhour1; //秒表 reg [3:0]mhour0; //秒表 reg alert; //当闹铃到时高电平输出 reg [7:0]count; reg [24:0]counter; reg enable; reg en1,en2;
wire second_en; always (posedge clk) //generate 1s begin if (clr) begin counter = 0; enable = 0; end else begin counter = counter +1; if (counter == 25'd249) // 仿真时可将闸门信号设为0.00001s,加快仿真速度 // if (counter == 25'd24999999) // 执行设计时将闸门信号改回为1s begin enable = ~enable; counter = 25'd0; end end end always (posedge clk) //????? begin if (clr) begin en1 <= 1'b0; en2 <= 1'b0; end else begin en1 <= enable; en2 <= en1; end end assign second_en = (!en1) && (en2); always (posedge clk) begin if(clr) begin amin1<=0; amin0<=0;
ahour1<=0; ahour0<=0; smin1<=0; smin0<=0; shour1<=0; shour0<=0; mmin1<=0; mmin0<=0; mhour1<=0; mhour0<=0; count<=0; end else if (second_en) begin count<=count+1; /////////////////////////////////////////////////////////////////////////////////////////// if(mode==2'b01) //闹铃调时状态 if(turn==1) //当turn为高电平时调整分位 if((amin1==5)&&(amin0==9)) begin amin1<=0; amin0<=0; end else if(amin0==9) begin amin1<=amin1+1; amin0<=0; end else amin0<= amin0+1; else //当turn为低电平时调整小时位 if((ahour1==2)&&(ahour0==3)) begin ahour1<=0; ahour0<=0; end else if(ahour0==9) begin ahour1<=ahour1+1; ahour0<=0; end