基于FPGA的VerilogHDL数字钟设计.docx
- 文档编号:29519146
- 上传时间:2023-07-24
- 格式:DOCX
- 页数:21
- 大小:300.82KB
基于FPGA的VerilogHDL数字钟设计.docx
《基于FPGA的VerilogHDL数字钟设计.docx》由会员分享,可在线阅读,更多相关《基于FPGA的VerilogHDL数字钟设计.docx(21页珍藏版)》请在冰豆网上搜索。
基于FPGA的VerilogHDL数字钟设计
基于FPGA的VerilogHDL数字钟设计
专业班级姓名学号
一、实验目的
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)在XilinxISE13.1软件中,利用层次化方法,设计实现模一百计数及显示的电路系统,设计模块间的连接调用关系,编写并输入所设计的源程序文件。
3)对源程序进行编译及仿真分析(注意合理设置,以便能够在验证逻辑的基础上尽快得出仿真结果)。
4)输入管脚约束文件,对设计项目进行编译与逻辑综合,生成下载所需.bit文件。
5)在Basys2实验板上下载所生成的.bit文件,观察验证所设计的电路功能。
3、实验设计
功能说明:
实现时钟,时间校时,闹铃定时,秒表计时等功能
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时,暂停。
4、实验代码
时钟模块
moduleclock(clk,
clr,
pause,
turn,
mode,
sec,
min1,
min0,
hour1,
hour0,
alert,
LD_alert
);
inputclk;//时钟信号(50MHz)
inputclr;//清零键
inputpause;//秒表暂停键
inputturn;//调整分还是小时位的控制
input[1:
0]mode;//决定时钟显示功能状态
outputsec;//接发光二极管
output[3:
0]min1;//用于输出接数码管4
output[3:
0]min0;//用于输出接数码管3
output[3:
0]hour1;//用于输出接数码管2
output[3:
0]hour0;//用于输出接数码管1
outputalert;//接发光二极管,代替蜂鸣器
outputLD_alert;//当闹铃设定后,发光二极管显示
wiresec;//秒位显示
wireLD_alert;//用于闹铃存在时的提醒显示
//wireclk1;//时钟1s
//wireclk2;//时钟100ms,用于秒表最小计时单位
//wireclr1;
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;//秒表
regalert;//当闹铃到时高电平输出
reg[7:
0]count;
reg[24:
0]counter;
regenable;
regen1,en2;
wiresecond_en;
always(posedgeclk)//generate1s
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(posedgeclk)//?
?
?
?
?
beginif(clr)beginen1<=1'b0;en2<=1'b0;endelsebeginen1<=enable;en2<=en1;endendassignsecond_en=(!
en1)&&(en2);
always(posedgeclk)
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
elseif(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
else
ahour0<=ahour0+1;
////////////////////////////////////////////////////////////////////////////////////////
if(mode==2'b10)//时钟调时状态
if(turn==1)//当turn为高电平时调整分位
if((smin1==5)&&(smin0==9))
begin
smin1<=0;
smin0<=0;
end
else
if(smin0==9)
begin
smin1<=smin1+1;
smin0<=0;
end
else
smin0<=smin0+1;
else//当turn为低电平时调整小时位
if((shour1==2)&&(shour0==3))
begin
shour1<=0;
shour0<=0;
end
else
if(shour0==9)
begin
shour1<=shour1+1;
shour0<=0;
end
else
shour0<=shour0+1;
else//以下是常规显示
begin
if(count==59)
begin
count<=0;
smin0<=smin0+1;
if(smin0==9)
begin
smin0<=0;
smin1<=smin1+1;
if(smin1==5)
begin
smin1<=0;
shour0<=shour0+1;
if(shour0==3)
begin
shour0<=0;
shour1<=shour1+1;
if(shour1==2)
shour1<=0;
end
end
end
end
end
////////////////////////////////////////////////////////////////////////////////
if(mode==2'b11)
begin//秒表计时状态
if(pause==0)//当pause为低电平时开始计时
begin
mmin0<=mmin0+1;
if(mmin0==9)
begin
mmin0<=0;
mmin1<=mmin1+1;
if(mmin1==9)
begin
mmin1<=0;
mhour0<=mhour0+1;
if(mhour0==9)
begin
mhour0<=0;
mhour1<=mhour1+1;
if(mhour1==9)
mhour1<=0;
end
end
end
end
end
end
end
assignLD_alert=(amin1|amin0|ahour1|ahour0)?
1:
0;//当闹铃有定时后LD_alert发光以示闹铃已定
assignsec=enable;//将秒针接到LED灯
always(posedgeclk)
begin
if(clr)
alert<=0;
else
if((amin1==smin1)&&(amin0==smin0)&&(ahour1==shour1)&&(ahour0==shour0))
alert<=1;//对闹铃做检查,时间到时发光
elsealert<=0;
end
//以下为选择显示模块
always(posedgeclk)
begin
if(clr)
begin
min1<=0;
min0<=0;
hour1<=0;
hour0<=0;
end
else
begin
case(mode)
2'b01:
begin//mode=01时,显示闹铃模块
min1<=amin1;
min0<=amin0;
hour1<=ahour1;
hour0<=ahour0;
end
2'b10:
begin//mode=10时,显示校时模块
min1<=smin1;
min0<=smin0;
hour1<=shour1;
hour0<=shour0;
end
2'b11:
begin//mode=11时,显示秒表模块
min1<=mmin1;
min0<=mmin0;
hour1<=mhour1;
hour0<=mhour0;
end
2'b00:
begin//其他状态,显示普通时钟模块
min1<=smin1;
min0<=smin0;
hour1<=shour1;
hour0<=shour0;
end
endcase
end
end
endmodule
译码模块
moduledisplay(q,ctr,h1,h0,m1,m0,clk,reset);
output[6:
0]q;
output[3:
0]ctr;
input[3:
0]h1,h0,m1,m0;
inputclk,reset;
reg[6:
0]q;
reg[25:
0]count;
reg[3:
0]temp;
reg[3:
0]scan;
//delayyanshi(clk,clk2);
always(posedgeclk)
begin
if(reset)
begin
count=0;
end
else
begin
count=count+1;
end
end
always(posedgeclk)//SegScan
begin
if(reset)
begin
scan<=4'b0000;
end
else
case(count[1:
0])//仿真时将扫描信号频率加快1000倍
//case(count[11:
10])//执行设计时将扫描频率改回
2'b00:
scan<=4'b0111;
2'b01:
scan<=4'b1011;
2'b10:
scan<=4'b1101;
2'b11:
scan<=4'b1110;
endcase
end
assignctr=scan;
always(posedgeclk)//SegScan
begin
if(reset)
begin
temp<=4'b0000;
end
else
case(count[1:
0])//仿真时将扫描信号频率加快1000倍
//case(count[11:
10])//执行设计时将扫描频率改回
2'b00:
temp<=h1;
2'b01:
temp<=h0;
2'b10:
temp<=m1;
2'b11:
temp<=m0;
endcase
end
always(posedgeclk)//数码管译码
begin
if(reset)
begin
q<=7'b0000000;
end
else
case(temp)
4'd0:
q<=7'b0000001;//0
4'd1:
q<=7'b1001111;//1
4'd2:
q<=7'b0010010;//2
4'd3:
q<=7'b0000110;//3
4'd4:
q<=7'b1001100;//4
4'd5:
q<=7'b0100100;//5
4'd6:
q<=7'b0100000;//6
4'd7:
q<=7'b0001111;//7
4'd8:
q<=7'b0000000;//8
4'd9:
q<=7'b0000100;//9
default:
q<=7'b0000001;
endcase
end
endmodule
UCF文件
NET"clk"LOC="B8";#50M
#PinassignmentforDispCtl
#ConnectedtoBasys2onBoard7qdisplay
NET"q<6>"LOC="L14";#Bank=1,Signalname=CA
NET"q<5>"LOC="H12";#Bank=1,Signalname=CB
NET"q<4>"LOC="N14";#Bank=1,Signalname=CC
NET"q<3>"LOC="N11";#Bank=2,Signalname=CD
NET"q<2>"LOC="P12";#Bank=2,Signalname=CE
NET"q<1>"LOC="L13";#Bank=1,Signalname=CF
NET"q<0>"LOC="M12";#Bank=1,Signalname=CG
#NET"dp"LOC="N13";#Bank=1,Signalname=DP
NET"ctr<3>"LOC="K14";#Bank=1,Signalname=AN3
NET"ctr<2>"LOC="M13";#Bank=1,Signalname=AN2
NET"ctr<1>"LOC="J12";#Bank=1,Signalname=AN1
NET"ctr<0>"LOC="F12";#Bank=1,Signalname=AN0
NET"reset"LOC="N3";#Bank=2,Signalname=SW7
NET"mode<1>"LOC="E2";#Bank=3,Signalname=SW6
NET"mode<0>"LOC="F3";#Bank=3,Signalname=SW5
NET"turn"LOC="G3";#Bank=3,Signalname=SW4
NET"pause"LOC="B4";#Bank=3,Signalname=SW3
NET"LD_alert"LOC="P7";#Bank=3,Signalname=LD2
NET"alert"LOC="M11";#Bank=2,Signalname=LD1
NET"sec"LOC="M5";#Bank=2,Signalname=LD0
testbench
moduletb_test;
//Inputs
regclk;
regreset;
reg[1:
0]mode;
regturn;
regpause;
//Outputs
wire[6:
0]q;
wire[3:
0]ctr;
wiresec;
wirealert;
wireLD_alert;
//InstantiatetheUnitUnderTest(UUT)
clkuut(
.clk(clk),
.reset(reset),
.mode(mode),
.turn(turn),
.pause(pause),
.q(q),
.ctr(ctr),
.sec(sec),
.alert(alert),
.LD_alert(LD_alert)
);
parameterPERIOD=10;
alwaysbegin
clk=1'b0;
#(PERIOD/2)clk=1'b1;
#(PERIOD/2);
end
initialbegin
//InitializeInputs
reset=1;
mode=2'b00;
turn=0;
pause=0;
//Wait100nsforglobalresettofinish
#500;
reset=0;
mode=2'b00;
turn=0;
#600000;
mode=2'b01;
turn=0;
#60000;
mode=2'b01;
turn=1;
#60000;
mode=2'b10;
turn=0;
#60000;
mode=2'b10;
turn=1;
#60000;
mode=2'b11;
#60000;
pause=1;
#60000;
reset=1;
//Addstimulushere
end
endmodule
5、仿真
进入ISim仿真波形界面
(1)仿真,运行1ms,将波形结果调整为适合的大小。
(2)这时我们可以分别点开clock模块和display模块查看具体的信号变化是否正确。
我们先看clock模块。
(3)当mode=00时,实现正常时钟显示功能。
在脉冲second_en到来时,count做计数加1,此时小时位是shour1,shour0,分钟位是smin1,smin0,将这几个相关信号在波形窗口中位置做个调整放到一起来查看。
当count计数到59时,分钟位smin0实现加1变化,由0变为1;此时结果是正确的。
(4)当mode=2’b01时,实现闹铃模块。
当turn=1时,调整分位amin1、amin0;当turn=0时,调整小时位ahour1、ahour0。
将相关信号放在一起查看,由图可知,当turn为低时,调整小时位,ahour0计
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 FPGA VerilogHDL 数字 设计