logo资料库

Verilog数字钟设计实验报告.doc

第1页 / 共18页
第2页 / 共18页
第3页 / 共18页
第4页 / 共18页
第5页 / 共18页
第6页 / 共18页
第7页 / 共18页
第8页 / 共18页
资料共18页,剩余部分请下载后查看
基于FPGA实现多功能数字钟
摘要
基于 FPGA 实现多功能数字钟 摘要 本文利用Verilog HDL语言自顶向下的设计方法设计多功能数字钟,并通过 ISE完成综合、仿真。此程序通过下载到FPGA 芯片后,可应用于实际的数字钟显 示中,实现了基本的计时显示和设置,调整时间,闹钟设置的功能。 [关键词] FPGA;Verilog HDL;数字钟
一、多功能数字钟的设计 设计一个多功能数字时钟,具有时分、秒计数显示、闹钟功能。能够利用按 键实现对闹钟时间的设定并在当前显示时间到时后能够进行闹钟提示。能够利用 按键实现“较时”、“较分”功能,随时对数码管的显示进行校正和校对。数字 中系统主要由系统时钟,三个功能按键(mode,turn,change),FPGA,数码管 和蜂鸣器部分组成。 数码管 显示模块 分 频 模 块 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 按键可用于跑表的 暂停与开始。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 else count1<=change; {LD_min,LD_hour}<=2; end//////指示当前调整的是分钟 begin counta<=change; {LD_min,LD_hour}<=1; end/////指示当前调整的是小时 {count2,countb}<=0; end 1: begin //////1:调节闹钟功能 if(fm) begin else count2<=change; {LD_min,LD_hour}<=2; end/////指示当前调整的是分 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
分享到:
收藏