Verilog数字钟设计实验报告
基于FPGA实现多功能数字钟
——电子系
071180094
王丛屹
摘要
本文利用Verilog HDL语言自顶向下的设计方法设计多功能数字钟,并通过ISE完成综合、仿真。此程序通过下载到FPGA 芯片后,可应用于实际的数字钟显示中,实现了基本的计时显示和设置,调整时间,闹钟设置的功能。
[关键词] FPGA,Verilog HDL,数字钟
一、多功能数字钟的设计
设计一个多功能数字时钟,具有时分、秒计数显示、闹钟功能。能够利用按键实现对闹钟时间的设定并在当前显示时间到时后能够进行闹钟提示。能够利用按键实现“较时”、“较分”功能,随时对数码管的显示进行校正和校对。数字
,turn,change),FPGA,数码管中系统主要由系统时钟,三个功能按键(mode
和蜂鸣器部分组成。
数码管
显示模块
分
蜂计时模块 闹钟模块 频鸣模器 Clk 块
控制模块
图: 多功能数字钟总体设计模块
以下就各个模块说明其功能
1. 分频模块
由于FPGA内部提供的时钟信号频率大约为50MHz,在这需要将它转化成1Hz的标准时钟信号供数字钟的计时显示;在此我采用了级联分频法。
RTL图如下:
代码如下:
//fenpin
module fenpin(clk,clk_1Hz,clk_100Hz,clk_1k); output clk_1Hz,clk_100Hz,clk_1k; input clk;
reg clk_1Hz=0,clk_3=0,clk_1=0,clk_2=0,clk_1k=0; reg [6:0] cnt1=0,cnt2=0,cnt3=0,cnt4=0,cnt5=0; wire clk_100Hz;
always @(posedge clk)
begin
if ( cnt1 < 156/2-1) /////////////////////////////////////////////156分频,生成1MHz信号
begin
cnt1 <= cnt1 + 1;
end
else
begin
cnt1 <= 0;
clk_1 <= ~clk_1;
end
end
always @(posedge clk_1)
if ( cnt2 < 156/2-1) /////////////////////////////////////100分频,生成10000Hz信号
begin
cnt2 <= cnt2 + 1;
end
else
begin
cnt2 <= 0;
clk_2 <= ~clk_2;
end
always @(posedge clk_2)
if ( cnt5 < 10/2-1) /////////////////////////////////////////10分频,生成1kHz标准信号
begin
cnt5<= cnt5 + 1;
end
else
begin
cnt5<= 0;
clk_1k<= ~clk_1k;
end
always @(posedge clk_2)
if ( cnt3 < 100/2-1) //////////////////////////////////////////100分频,生成100Hz信号
begin
cnt3 <= cnt3 + 1;
end
else
begin
cnt3 <= 0;
clk_3 <= ~clk_3;
end
assign clk_100Hz=clk_3;
always @(posedge clk_3)
if ( cnt4 < 100/2-1) /////////////////////////////////////////100分频,生成1Hz标准信号
begin
cnt4<= cnt4 + 1;
end
else
begin
cnt4<= 0;
clk_1Hz<= ~clk_1Hz;
end
endmodule
最终输出的是1Hz,100Hz,1kHz的标准时钟信号clk_1Hz ,clk_100Hz,clk_1k。
2、 计时模块
原理:m是模式按键,当m=0时,进入计时模式,在计时模式下可以进行时间调整。num3,num4产生加速调整时间,当其值为1时,可以快速调整时间,该调整时间的频率由clk提供。counta,count1是手动调节时间。Turn接按键,可以改变当前调节的是小时还是分钟,长按turn键还可以使秒钟信号清零。sec1,min1,hour1输出的是计时的秒,分,时。 RTL图如下:
代码如下:
//jishi
module jishi(clk,clk_1Hz,
turn,//// turn: 接按键,在手动校时功能时,选择是调整小时,还是分钟;若长时间按住该键,还可使秒信号清零,用于精确调时
mode,count1,counta,sec1,min1,hour1,num3,num4); input clk,clk_1Hz,turn,num3,num4;
input mode;
input count1,counta;
output [7:0] sec1,min1;
output [7:0] hour1;
wire clk_1Hz,ct1,cta,turn,num3,num4; reg [7:0] sec1=0,min1=0;
reg [7:0] hour1=0;
reg [1:0] m;
wire count1,counta;
reg minclk,hclk;
always @(posedge mode) //mode 信号控制系统在三种功能间转换 begin
if(m==4) m<=0;
else m<=m+1;
end
/////秒钟计时模块//////
always @(posedge clk_1Hz)
if((sec1==8'h59)|turn&(!m))///////若长时间按住该键,还可使秒信号清零,用于精确调时。
begin
sec1<=0; //按住“turn”按键一段时间,秒信号可清零,该功能用于手动精确调时 if(!(turn&(!m))) minclk<=1;///产生进位
end
else begin
if(sec1[3:0]==4'b1001)
begin sec1[3:0]<=4'b0000; sec1[7:4]<=sec1[7:4]+1; end
else sec1[3:0]<=sec1[3:0]+1; minclk<=0;
end
////////分钟计时模?///
assign m_clk=minclk||count1;/////m_clk产生进位或校正改变 assign ct1=(num3&clk)|(!num3&m_clk); //ct1 用于计时、校时中的分钟计数 always @(posedge ct1)
begin
if(min1==8'h59) begin min1<=0; hclk<=1; end
else begin
if(min1[3:0]==9)
begin min1[3:0]<=0; min1[7:4]<=min1[7:4]+1; end
else min1[3:0]<=min1[3:0]+1; hclk<=0;
end
end
////////小时计时模块///
assign h_clk=hclk||counta;//////h_clk产生进位或校正改变 assign cta=(num4&clk)|(!num4&h_clk); //cta 用于计时、校时中的小时计数
always @(posedge cta)
if(hour1==8'h23) hour1<=0;
else if(hour1[3:0]==9)
begin hour1[7:4]<=hour1[7:4]+1; hour1[3:0]<=0; end else hour1[3:0]<=hour1[3:0]+1;
endmodule
3、 闹钟模块
原理:num1,num2产生加速调整时间,当其值为1时,可以快速调整时间,该调整时间的频率由clk提供。countb,count2是手动调节闹钟时间。amin,ahour是输出的闹钟的分钟和小时,LD_alert指示当前是否开启闹钟。
RTL图如下:
代码如下:
// Alarm
module Alarm(clk,amin,ahour,num1,num2,count2,countb,LD_alert);
input clk,num1,num2,count2,countb;
output [7:0] amin;
output [7:0] ahour;
output LD_alert;
wire LD_alert;
reg [7:0] amin=0;
reg [7:0] ahour=0;
assign ct2=(num1&clk)|(!num1&count2); //ct2 用于定时状态下调整分钟信号
assign LD_alert=(ahour|amin)?1:0;//指示是否进行了闹铃定时
always @(posedge ct2)
if(amin==8'h59) amin<=0;
else if(amin[3:0]==9)
begin amin[3:0]<=0; amin[7:4]<=amin[7:4]+1; end else amin[3:0]<=amin[3:0]+1;
assign ctb=(num2&clk)|(!num2&countb); ////ctb 用于定时状态调节小时信号
always @(posedge ctb)
if(ahour==8'h23) ahour<=0;
else if(ahour[3:0]==9)
begin ahour[3:0]<=0; ahour[7:4]<=ahour[7:4]+1; end else ahour[3:0]<=ahour[3:0]+1;
endmodule
4、 控制模块(1)
原理:m是模式按键,当m=0时,指当前输出的是计时功能;当m=1时,指当前调整的是闹钟时间;当m=2时,指当前调整的是计时时间;当m=3时,此时turn按键可用于跑
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
的
暂停与开始。change 接按键,手动调整时,每按一次,计数器加1;如果长按,则连续快速加 1,用于快速调时和定时;turn接按键,在手动校时功能时,选择是调整小时,还是分钟;若长时间按住该键,还可使秒信号清零,用于精确调时。count1,count2,counta,countb分别是用来调节计时时间和闹钟时间。LD_min,LD_hour,指示当前调节的是分钟还是小时。 RTL图
代码如下:
// ctrol
module ctrol(change,turn,count1,count2,counta,countb,pause,LD_min,LD_hour,mode);
input change,mode,turn;
output count1,count2,counta,countb,pause,LD_min,LD_hour;
reg [1:0] m;
reg fm=0,count1=0,count2=0,counta=0,countb=0,pause=0,LD_min=0,LD_hour=0;
wire mode,turn,change;
always @(posedge mode) //mode 信号控制系统在三种功能间转换
begin
if(m==4) m<=0;
else m<=m+1;
end
always @(posedge turn)//////////接按键,在手动校时功能时,选择是调整小时,还是分钟; begin
fm<=~fm;
end
always @ (m or fm or change)
begin
case(m)
3: begin ////////3:跑表功能;
if(fm)
pause=1;
else
pause=0;
end
2: begin ////////2:调节时间功能;
if(fm)
begin count1<=change; {LD_min,LD_hour}<=2; end//////指示当前调整的是分钟
else
begin counta<=change; {LD_min,LD_hour}<=1; end/////指示当前调整的是小时
{count2,countb}<=0;
end
1: begin //////1:调节闹钟功能
if(fm)
begin count2<=change; {LD_min,LD_hour}<=2; end/////指示当前调整的是分
else
begin countb<=change; {LD_min,LD_hour}<=1; end/////指示当前调整的是小时
{count1,counta}<=0;
end
0: begin {count1,count2,counta,countb,LD_min,LD_hour}<=0;end ////0:计时功能
endcase
end
endmodule
5、 控制模块(2)
原理:此模块是加速调节时间模块,count1,count2,counta,countb是手动调节时间,当长时间按这些键时,num1,num2,num3,num4的值会发生变化,当他们值有为1时,对应的调节会快速加1。
代码如下:
// faster
module faster(clk,num1,num2,num3,num4,count1,count2,counta,countb);
input clk;
input count1,count2,counta,countb;
output num1,num2,num3,num4;
wire count1,count2,counta,countb;
reg[2:0] loop1=0,loop2=0,loop3=0,loop4=0;
reg num1,num2,num3,num4;
always @(negedge clk)//如果长时间按下“change”键,则生成“num*”信号用于连续快速加1 if(count2) begin
if(loop1==3) begin loop1<=0; num1<=1; end else
begin loop1<=loop1+1; num1<=0; end end
else begin loop1<=0; num1<=0; end
always @(negedge clk)
if(countb) begin
if(loop2==3) begin loop2<=0; num2<=1; end else
begin loop2<=loop2+1; num2<=0; end end
else begin loop2<=0; num2<=0; end
always @(negedge clk)
if(count1) begin
if(loop3==3) begin loop3<=0; num3<=1; end else
begin loop3<=loop3+1; num3<=0; end end
else begin loop3<=0; num3<=0; end
always @(negedge clk)
if(counta) begin
if(loop4==3) begin loop4<=0; num4<=1; end else
begin loop4<=loop4+1; num4<=0; end end
else begin loop4<=0; num4<=0; end endmodule
6、 显示模块
原理:同时输入计时模块的时间和闹钟模块的时间,选择m值,当m=0时,指当前输出的是计时模块的时间;当m=1时,指当前输出的是闹钟模块的时间;当m=2时,指当前输出的是调节计时模块的时间;当m=3时,指当前输出的是跑表计时的时间。
代码如下:
// faster
module show(min1,sec1,amin,hour1,ahour,MSH,MSL,SH,SL,MH,ML,min,sec,hour,mode);
input [7:0] min1,sec1,amin;
input [7:0] hour1,ahour;
input[3:0] MSH,MSL,SH,SL,MH,ML;
input mode;
output [7:0] min,sec;
output [7:0] hour;
reg [7:0] min,sec;
reg [7:0] hour;
reg [1:0] m;
always @(posedge mode) //mode 信号控制系统在三种功能间转换
begin
if(m==4) m<=0;
else m<=m+1;
end
always @(min1 or sec1 or amin or hour1 or ahour or m)
begin
case(m)
0: begin hour<=hour1; min<=min1; sec<=sec1; end
1: begin hour<=ahour; min<=amin; sec<=8'hzz; end 2: begin hour<=hour1; min<=min1; sec<=8'hzz; end 3: begin hour<={SH,SL}; min<={MSH,MSL}; sec<={MH,ML}; end
endcase
end
endmodule
7、 响铃模块
原理:同时输入计时模块的时间和闹钟模块的时间。当计时模块的时间快到达整点时,会产生响声;当计时模块的时分同时等于闹钟模块的时分时,也产生响铃。这时alert为1,如果在这时按住change键,可以屏蔽闹钟响铃。
代码如下:
// ring
module ring(clk,clk_1k,min1,sec1,amin,hour1,ahour,change,alert);
input [7:0] min1,sec1,amin;
input [7:0] hour1,ahour;
input change,clk,clk_1k;
output alert;
wire [7:0] min1,sec1,amin;
wire [7:0] hour1,ahour;
wire change;
reg alert1=0,alert2=0;
reg [1:0] sound;
reg ear;
wire alert;
wire clk_1k,clk;
always @ (posedge clk)
if((min1==amin)&&(hour1==ahour)&&(amin|ahour)&&(!change))
if(sec1<30) alert1<=1;
else alert1<=0;
else alert1<=0;
always @ (posedge clk)
begin
if(sound==3) begin sound<=0; ear<=1; end //ear 信号用于产生或屏蔽声音
else begin sound<=sound+1; ear<=0; end if((min1==8'h59)&&(sec1>8'h54)||(!(min1|sec1))) if(sec1>8'h54) alert2<=ear&clk_1k; //产生短音
else alert2<=!ear&clk_1k; //产生长音
else alert2 <= 0; //停止发声
end
///assign alert=((alert1)?clk_100Hz&clk:0)|alert2;//产生闹铃音或整点报时音 assign alert=((alert1)?clk_1k&clk:0)|alert2; //产生闹铃音或整点报时音 endmodule
8、 跑表模块
原理:输入该模块的是100Hz时钟信号。百分秒是模为100的BCD码计数器,为方便
数码管显示,将百分秒的两位分别用4位的MSH(百分秒高位),MSL(百分秒低位)
表示。这样MSH,MSL就分别对应每一个数码管显示的BCD码。同理,秒信号为模为
60的BCD码计数器,两位也用四位的SH(秒高位),SL(秒低位)。此时turn键可用
作跑表的pause键,按下turn键后跑表暂停,再按下后秒表启动。此外clr按键可实现
跑表的异步清零。
// paobiao
/*信号定义:
clk_100Hz: clk_100Hz 为时钟信号;
clr: 为异步复位信号;
pause: 为暂停信号;
MSH,MSL: 百分秒的高位和低位;
SH,SL: 秒信号的高位和低位;
MH,ML: 分钟信号的高位和低位。 */
module paobiao(clk_100Hz,clr,pause,MSH,MSL,SH,SL,MH,ML);
input clk_100Hz,clr;
input pause;
output[3:0] MSH,MSL,SH,SL,MH,ML;
reg[3:0] MSH,MSL,SH,SL,MH,ML;
reg cn1,cn2; //cn1 为百分秒向秒的进位,cn2 为秒向分的进位
//百分秒计数进程,每计满100,cn1 产生一个进位
always @(posedge clk_100Hz or posedge clr) begin
if(clr) begin //异步复位
{MSH,MSL}<=8'h00;
cn1<=0;
end
else if(!pause) //PAUSE 为0 时正常计数,为1 时暂停计数
begin
if(MSL==9) begin
MSL<=0;
if(MSH==9)
begin MSH<=0; cn1<=1; end
else MSH<=MSH+1;
end
else begin
MSL<=MSL+1; cn1<=0;
end
end
end
//秒计数进程,每计满60,cn2 产生一个进位 always @(posedge cn1 or posedge clr)
begin
if(clr) begin //异步复位
{SH,SL}<=8'h00;
cn2<=0;
end
else if(SL==9) //低位是否为9
begin
SL<=0;
if(SH==5)
begin SH<=0; cn2<=1; end
else SH<=SH+1;
end
else
begin SL<=SL+1; cn2<=0; end
end
//分钟计数进程,每计满60,系统自动清零
always @(posedge cn2 or posedge clr)
begin
if(clr)
begin {MH,ML}<=8'h00; end //异步复位
else if(ML==9) begin
ML<=0;
if(MH==5) MH<=0;
else MH<=MH+1;
end
else ML<=ML+1;
end
endmodule
三、总体设计构思套路:
1、关于模式信号mode选择各个功能显示的构思:
考虑到使用mode按键产生0、1信号在正常时间显示、调节时间功能、调节闹钟功能和跑表功能这四个功能之间的转换。所以mode信号的作用主要体现在控制模块(1)和显示模块中,虽然计时模块中也用到mode信号,但是它只是turn信号将秒信号清零的辅助作用,保证只有在m=0(即普通时钟显示)下turn信号清零功能才起作用,在校时功能下只能是分、小时的切换和跑表下的暂停功能。
a、 在控制模块下的作用:
在控制模块下,其实mode和turn信号的作用更像2-4译码器的功能,将change数字上
加信号按不同的mode和turn分成四个信号,分别是count1(时间显示下的分信号)、
counta(时间显示下的小时信号)、count2(闹铃显示下的分信号)、countb(闹铃显示下的小
时信号)。
b、 在显示模块下的作用:
同在控制模块下的作用。只是将turn信号选出的小时和分钟在同一个mode下一起送至
数码管显示。
2、关于时间调整和闹铃时间调整中数字上加的原理:
对于这个问题,我们要考虑两种情况,首先是时间调整的情况:因为在时间调整下,数字的上加不仅受到change信号的作用(即人工调时),还受本身在1Hz信号下计时而随时发生的累加。而闹铃时间调整不存在这种情况,因为闹铃下的时间数字发生上加只可能人工调节(change信号作用下)的结果。
a、 时间调整下的上加:
由于在控制模块(2)下又设置了快加的功能,所以有三部分信号对上加起作用,一是
快加下的numXclk,表示以原始时钟的速率上加,二是慢加下的change具体到各模块、
各位的count1或counta,三是秒信号记到9向分信号的进位。
b、 闹铃时间调整下的上加:
该部分原理同上,只是少了低位记到9向高位的进位。所以只有两部分组成,一是快加
下的numXclk,表示以原始时钟的速率上加,二是慢加下的change具体到各模块、各位
的count2或countb。
上述原理可用下面的信号
流程
快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计
图表示;
Change信号
Mode和turn进行译码
选择
count1 counta count2 countb
num3 num4 num1 num2
hc ct1 minclk cta ct2 ctb lk
hour1 amin ahour min1
【hour, min】送至数码管显
示
Mode选择
四(各工作模式仿真波形 1.时钟正常计时波形
00:00:59时刻波形
00:59:59时刻波形
23:59:59时刻波形
2.定时闹钟波形
如图所示为01:02:00-01:02:59的一分钟闹钟波形。
3.仿电台报时波形
如图所示,在任意小时59分的51、53、55、57秒内蜂鸣器为低频(512Hz)信号输出,在59秒内蜂鸣器为高频(1024Hz)信号输出,实现模仿电台报时功能。
3.整点报时波形
如图所示,在06:00:00后的6秒内,蜂鸣器前半秒无输入,后半秒有高频(1024Hz)输入,达到整点报时功能。在N小时整时刻,蜂鸣器会鸣响N次。如此仿真中为六点,响六下
分计数器仿真波形图:
小时计数器仿真波形图:
五、在FPGA板上调试过程如下:
1.当前m=0,输出的是计时模块的时间;
LD_alert=0,表示没有设置闹钟。
2.当m=1时,输出的是闹钟时间。改变change的值,可以调节闹钟的时间。 可以看出设置得闹钟为8:25。LD-alert=1提示设置了闹钟。
3.当m=2or3时,输出的是调整计时模块的时间。改变change的值,可以调节时间。 可以看出,时间调整为8:21。
4.从下可以看出,LD_alert=1,表明设置有闹钟。alert=0,表示闹钟时间还没有到。
时间为8:25:00,闹钟报警,alert=1,报警时间长为30秒,如果按住change键,则可以屏蔽闹铃。
时间为8:25:31,闹铃停止。
测试成功~
六(小结
通过近来对FPGA的学习,我对ISE软件总体操作步骤已比较熟悉。接下来的时间是要提高对FPGA的掌握能力,将FPGA运用到数字信号处理和通信原理上。
,另外,对Verilog语言的学习不仅是能读懂别人的程序,更重要的是能写出条理清晰的程序。通过做多功能数字钟,我发现自己对Verilog语言还不是很熟悉,接下来的时间要加强语言的学习,多看一些语言方面的书籍。