基于FPGA的数字钟设计.docx

上传人:b****0 文档编号:9746054 上传时间:2023-05-20 格式:DOCX 页数:22 大小:351.61KB
下载 相关 举报
基于FPGA的数字钟设计.docx_第1页
第1页 / 共22页
基于FPGA的数字钟设计.docx_第2页
第2页 / 共22页
基于FPGA的数字钟设计.docx_第3页
第3页 / 共22页
基于FPGA的数字钟设计.docx_第4页
第4页 / 共22页
基于FPGA的数字钟设计.docx_第5页
第5页 / 共22页
基于FPGA的数字钟设计.docx_第6页
第6页 / 共22页
基于FPGA的数字钟设计.docx_第7页
第7页 / 共22页
基于FPGA的数字钟设计.docx_第8页
第8页 / 共22页
基于FPGA的数字钟设计.docx_第9页
第9页 / 共22页
基于FPGA的数字钟设计.docx_第10页
第10页 / 共22页
基于FPGA的数字钟设计.docx_第11页
第11页 / 共22页
基于FPGA的数字钟设计.docx_第12页
第12页 / 共22页
基于FPGA的数字钟设计.docx_第13页
第13页 / 共22页
基于FPGA的数字钟设计.docx_第14页
第14页 / 共22页
基于FPGA的数字钟设计.docx_第15页
第15页 / 共22页
基于FPGA的数字钟设计.docx_第16页
第16页 / 共22页
基于FPGA的数字钟设计.docx_第17页
第17页 / 共22页
基于FPGA的数字钟设计.docx_第18页
第18页 / 共22页
基于FPGA的数字钟设计.docx_第19页
第19页 / 共22页
基于FPGA的数字钟设计.docx_第20页
第20页 / 共22页
亲,该文档总共22页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

基于FPGA的数字钟设计.docx

《基于FPGA的数字钟设计.docx》由会员分享,可在线阅读,更多相关《基于FPGA的数字钟设计.docx(22页珍藏版)》请在冰点文库上搜索。

基于FPGA的数字钟设计.docx

基于FPGA的数字钟设计

基于FPGA的多功能数字钟

一、设计题目

基于XilinxFPGA的多功能数字钟设计

二、设计目的

1.掌握可编程逻辑器件的应用开发技术

——设计输入、编译、仿真和器件编程;

2.熟悉一种EDA软件使用;

3.掌握Verilog设计方法;

4.掌握分模块分层次的设计方法;

5.用Verilog完成一个多功能数字钟设计;

6.学会FPGA的仿真。

三、设计内容

设计实验项目九多功能电子钟

✧功能要求:

利用实验板设计实现一个能显示时分秒的多功能电子钟,具体要求为:

基本功能:

1)准确计时,以数字形式显示时、分、秒,可通过按键选择指示当前显示时间范围模式;

2)计时时间范围00:

00:

00-23:

59:

59

3)可实现校正时间功能;

4)可通过实现时钟复位功能:

00:

00:

00

扩展功能:

1)定时报:

时间自定(不要求改变),闹1分钟(1kHz)---利用实验板LED或外接电路实现。

2)仿广播电台正点报时:

XX:

59:

[51,53,55,57(500Hz);59(1kHz)]---利用实验板LED或外接电路实现。

3)报整点时数:

XX:

00:

[00.5-XX.5](1kHz),自动、手动---利用实验板LED或外接电路实现。

4)手动输入校时;

5)手动输入定时闹钟;

6)万年历;

7)其他扩展功能;

✧设计步骤与要求:

1)计算并说明采用Basys2实验板时钟50MHz实现系统功能的基本原理。

2)在XilinxISE13.1软件中,利用层次化方法,设计实现模一百计数及显示的电路系统,设计模块间的连接调用关系,编写并输入所设计的源程序文件。

3)对源程序进行编译及仿真分析(注意合理设置,以便能够在验证逻辑的基础上尽快得出仿真结果)。

4)输入管脚约束文件,对设计项目进行编译与逻辑综合,生成下载所需.bit类型文件。

5)在Basys2实验板上下载所生成的.bit文件,观察验证所设计的电路功能。

四、总体设计思路

主体分为分频模块,正常时间模块(包含两个模60计数器和一个模24计数器子模块),闹钟模块(分为一个模60计数器模块,一个模24计数器模块,四个比较器模块),电台报时模块,数码管显示模块(分为模式选择模块,片选信号及扫描程序模块,和译码模块)。

将各模块连接好各接线口即得到数字钟顶层模块complete.sch。

五、各模块设计及源代码

1.分频模块

分频模块要将50MHz的时钟信号分成三个分别为1Hz,500Hz,1kHz的三个脉冲信号,设置三个计数器,在三个频率信号分别对应的延时时间进行翻转,就可以得到三个不同的脉冲信号。

源代码如下:

//freq.v

modulefreq(clk,_1Hz,_500Hz,_1kHz);

inputclk;

output_1Hz,_500Hz,_1kHz;

reg_1Hz=0,_500Hz=0,_1kHz=0;

reg[24:

0]cnt1=0,cnt2=0,cnt3=0;

always@(posedgeclk)

begin

if(cnt1<25'd24999999)

//if(cnt1<25'd249)

//做test仿真时让变化更快

cnt1<=cnt1+1;//未达到计数时间计数器加一

else

begin

_1Hz<=~_1Hz;//达到计时时间,信号翻转且计数器归零

cnt1<=0;

end

end

always@(posedgeclk)

begin

if(cnt2<25'd49999)

//if(cnt2<25'd49)

cnt2<=cnt2+1;

else

begin

_500Hz<=~_500Hz;

cnt2<=0;

end

end

always@(posedgeclk)

begin

if(cnt3<25'd24999)

//if(cnt3<25'd25)

cnt3<=cnt3+1;

else

begin

_1kHz<=~_1kHz;

cnt3<=0;

end

end

endmodule

2.时钟正常显示模块

正常显示模块分为时分秒三个子模块,分别对应一个模24计数器和两个模60计数器。

模24计数器和模60计数器设计都BCD码来表示时分秒的值,每个分为高位和低位,均对应一个十进制的数。

对模24计数器,每个脉冲信号来临时当低位小于9时加一;等于9时高位加一且低位置零;且高位小于3,低位小于9,超过时高低位均置零;当高位等于2时,低位只能到3,同时复位nCR低电平时高低位均置零。

同理可得模60计数器的设计。

根据这个思路,得到模24计数器源代码如下:

//counter24.v

modulecounter24(CntH,CntL,nCR,EN,CP);

inputnCR,EN,CP;

output[3:

0]CntH,CntL;//分别为高位和低位

reg[3:

0]CntH,CntL;

always@(posedgeCPornegedgenCR)

begin

if(~nCR){CntH,CntL}<=8'h00;//复位键清零

elseif(~EN){CntH,CntL}<={CntH,CntL};//使能信号有效则暂停

elseif((CntH>2)||(CntL>9)||((CntH==2)&&(CntL>=3)))

{CntH,CntL}<=8'b00;//出现计数错误全部清零

elseif((CntH==2)&&(CntL<3))

CntL<=CntL+1;//超过20时计数方式

elseif(CntL==9)

beginCntH<=CntH+1'b1;

CntL<=4'b0;//一般情况下计数方式

end

else

CntL<=CntL+1'b1;

end

 

模60计数器代码如下:

//counterM60.v

modulecounterM60(CntMH,CntML,nCR,EN,CP);

inputCP,EN,nCR;

output[3:

0]CntMH,CntML;

reg[3:

0]CntMH=0,CntML=0;

always@(posedgeCPornegedgenCR)

begin

if(~nCR)

{CntMH,CntML}<=8'b00;

elseif(~EN)

{CntMH,CntML}<={CntMH,CntML};

elseif(CntML>9||CntMH>5||(CntMH==5&&CntML==9))

begin

{CntMH,CntML}<=8'h00;

end

elseif(CntMH<5&&CntML==9)

begin

CntMH<=CntMH+1'b1;

CntML<=4'b0;

end

else

CntML<=CntML+1'b1;

end

endmodule

而时钟计时就是调用两个模60计数器和一个模24计数器,但相应的CP信号是需要修改的使得秒的60计数一周期可以使分加一,同时分钟跑一个周期能使得时针加一。

同时按照设计要求需要加入按键调时功能,将两个按键AdjHr和AdjMin分别作为调时针和分针的按键,按下时时针和分钟的脉冲信号变为1Hz脉冲,由此时针分钟会以1Hz的频率改变而达到调时间的目的。

设置分钟和时钟的驱动信号分别为MinCP,HrCP,则可以设置MinCP=AdjMin?

_1Hz:

(Second==8'h59);HrCP=AdjHr?

_1Hz:

({Minute,Second}==16'h5959);

源代码如下:

//Top_clock.v

moduletop_clock(Hour,Minute,Second,_1Hz,nCR,AdjMin,AdjHr);

input_1Hz,nCR,AdjMin,AdjHr;

output[7:

0]Hour,Minute,Second;//分别为时分秒输出

wire[7:

0]Hour,Minute,Second;

supply1Vdd;//设置使能

wireMinCP,HrCP;//定义激励信号

counterM60UT1(Second[7:

4],Second[3:

0],nCR,Vdd,_1Hz);

counterM60UT2(Minute[7:

4],Minute[3:

0],nCR,Vdd,~MinCP);

counter24UT3(Hour[7:

4],Hour[3:

0],nCR,Vdd,~HrCP);

assignMinCP=AdjMin?

_1Hz:

(Second==8'h59);//分钟激励

assignHrCP=AdjHr?

_1Hz:

({Minute,Second}==16'h5959);//时钟激励

endmodule

 

3.仿电台报时模块

设置ALARM为报时输出,Minute和Second分别为分钟信号和秒钟信号,先用if-else语句来进行Minute是否为59的判断,之后再用case语句在Second为51,53,55,57时输出500Hz的信号,在59时输出为1kHz的信号,在板子上没有输出声音的设备,就接入LED来验证是否正常报时。

//radio.v

moduleradio(ALARM,Minute,Second,_1kHz,_500Hz);

input_1kHz,_500Hz;

input[7:

0]Minute,Second;

outputALARM;

regALARM;

always@(MinuteorSecond)

if(Minute==8'h59)

case(Second)

8'h51,

8'h53,

8'h55,

8'h57:

ALARM=_500Hz;//500Hz方式输出,报时

8'h59:

ALARM=_1kHz;//59s以1kHz输出

default:

ALARM=1'b0;//一般不输出

endcase

elseALARM=1'b0;

endmodule

 

4.闹钟模块

闹钟模块分为设定闹钟(包含两个按键),闹钟正常响铃,一个关闭闹钟的按键CtrRing。

设定闹钟同样可以以1Hz脉冲为激励信号,其主体电路为一个以1Hz为激励信号的受SetMinkey控制的模60计数器和一个受SetHrkey控制的模24计数器,调用之前已经写好的模块即可。

同时响铃设置为ALARM_clock,受按键CtrRing控制。

设置四个比较器,分别为小时高位比较,小时低位比较,分钟高位比较和分钟低位比较。

当四个比较信号都为1时才会闹钟响铃。

比较器的设计很简单直接给出源代码:

//comparator.v

modulecomparator(EQU,A,B);

input[3:

0]A,B;

outputEQU;

assignEQU=(A==B);

endmodule

而闹钟主体源代码如下:

//ring.v

modulering(ALARM_clock,Set_Hr,Set_Min,Hour,Minute,Second,SetHrkey,SetMinkey,_1kHz,_500Hz,_1Hz,CtrRing);

outputALARM_clock;

output[7:

0]Set_Hr,Set_Min;//输出的闹钟设定时间

wireALARM_clock;

wire[7:

0]Set_Hr,Set_Min;

input_1kHz,_500Hz,_1Hz;

input[7:

0]Hour,Minute,Second;

inputSetHrkey,SetMinkey,CtrRing;//闹钟设定按键和关闭闹钟按键

supply1Vdd;//设置高电平

wireHrH_Cop,MinH_Cop,HrL_Cop,MinL_Cop;//中间变量,为设定闹钟时间和正常时间比较

wiretime_EQU;

counterM60SU1(Set_Min[7:

4],Set_Min[3:

0],Vdd,SetMinkey,_1Hz);//调用模60计数器模块

counter24SU2(Set_Hr[7:

4],Set_Hr[3:

0],Vdd,SetHrkey,_1Hz);

comparatorSU4(HrH_Cop,Set_Hr[7:

4],Hour[7:

4]);//调用比较器模块

comparatorSU5(HrL_Cop,Set_Hr[3:

0],Hour[3:

0]);

comparatorSU6(MinH_Cop,Set_Min[7:

4],Minute[7:

4]);

comparatorSU7(MinL_Cop,Set_Min[3:

0],Minute[3:

0]);

assigntime_EQU=(HrH_Cop&&HrL_Cop&&MinH_Cop&&MinL_Cop);//时间比较信号

assignALARM_clock=CtrRing?

(time_EQU&&(((Second[0]==1'b1)&&_500Hz)||((Second[0]==1'b0)&&_1kHz))):

1'b0;//设置闹铃输出

endmodule

5.数码管显示模块

之前的模块设置了两个音频信号输出ALARM和ALARM_clock,这里可以统一起来。

数码管既要显示闹钟设定时间,也要显示时钟正常显示时间。

设置一个按键mode来切换显示模式,为0时显示正常时间,为1时显示闹钟定时时间。

设置LED_Hr和LED_Min为得到的当前显示的时和分。

还有由LED_Hr和LED_Min到数码管的显示需要设计扫描程序,分为片选和译码模块。

分别贴出源代码如下:

模式选择模块:

//mode.v

modulemode(mode,Hour,Minute,Second,Set_Hr,Set_Min,LED_Hr,LED_Min,ALARM,ALARM_clock,ALARMout);

inputmode,ALARM,ALARM_clock;

input[7:

0]Hour,Minute,Second,Set_Hr,Set_Min;

output[7:

0]LED_Hr,LED_Min;

outputALARMout;

wireALARM,ALARM_clock;

wire[7:

0]Set_Hr,Set_Min;

assignALARMout=ALARM||ALARM_clock;//时钟响铃,闹钟和电台报时均有效

assignLED_Hr=mode?

Set_Hr:

Hour;//选择当前显示的小时

assignLED_Min=mode?

Set_Min:

Minute;//选择当前显示的分

endmodule

之后是译码模块

在配置引脚时将小数点DP配置为最高位,其余G,F,E,D,C,B,A按从高到低的顺序配置,低电平段码管亮,由此可以写出对应段码,源代码如下:

//translate.v

moduletranslate(Seg_in,Seg_outH,Seg_outL);

input[7:

0]Seg_in;//输入的数码

output[7:

0]Seg_outH;//翻译后的高位段码

output[7:

0]Seg_outL;//翻译后的低位段码

wire[7:

0]Seg_outH,Seg_outL;

reg[7:

0]Seg_outH1,Seg_outL1;

always@(Seg_in[7:

4])//高位译码

case(Seg_in[7:

4])

4'b0000:

Seg_outH1=8'b11000000;//0的段码

4'b0001:

Seg_outH1=8'b11111001;//1

4'b0010:

Seg_outH1=8'b10100100;//2

4'b0011:

Seg_outH1=8'b10110000;/3

4'b0100:

Seg_outH1=8'b10011001;//4

4'b0101:

Seg_outH1=8'b10010010;//5

4'b0110:

Seg_outH1=8'b10000010;//6

4'b0111:

Seg_outH1=8'b11111000;//7

4'b1000:

Seg_outH1=8'b10000000;//8

4'b1001:

Seg_outH1=8'b10010000;//9

default:

Seg_outH1=8'b10100011;//出错显示

endcase

always@(Seg_in[3:

0])//低位译码

case(Seg_in[3:

0])

4'b0000:

Seg_outL1=8'b11000000;

4'b0001:

Seg_outL1=8'b11111001;

4'b0010:

Seg_outL1=8'b10100100;

4'b0011:

Seg_outL1=8'b10110000;

4'b0100:

Seg_outL1=8'b10011001;

4'b0101:

Seg_outL1=8'b10010010;

4'b0110:

Seg_outL1=8'b10000010;

4'b0111:

Seg_outL1=8'b11111000;

4'b1000:

Seg_outL1=8'b10000000;

4'b1001:

Seg_outL1=8'b10010000;

default:

Seg_outL1=8'b10100011;

endcase

assignSeg_outH=Seg_outH1;

assignSeg_outL=Seg_outL1;

 

endmodule

之后是数码管片选信号的设置和扫描程序,以500Hz为扫描频率。

代码如下:

//trans.v

moduletrans(_500Hz,LED_Hr,LED_Min,SGG,SELE);

input[7:

0]LED_Hr,LED_Min;

input_500Hz;

output[7:

0]SGG;

output[3:

0]SELE;

wire[7:

0]SGML,SGMH,SGHL,SGHH;//经过翻译的段码

reg[1:

0]count=2'b00;//扫描的计数控制

wire[3:

0]SELE;//片选信号

wire[7:

0]SGG;//输入数码管的输出信号

reg[7:

0]SG;//数码管段码中间变量

reg[3:

0]SEL=1110;//片选中间变量

translateST1(LED_Hr,SGHH,SGHL);

translateST2(LED_Min,SGMH,SGML);

always@(posedge_500Hz)

case(count)

2'b00:

beginSG=SGML;//选中第一个数码管

SEL=4'b1110;

count=count+1'b1;//扫描信号不断加一,从而实现扫描

end

2'b01:

beginSG=SGMH;//选中第二个管

SEL=4'b1101;

count=count+1'b1;

end

2'b10:

beginSG=SGHL;//选中第三个管

SEL=4'b1011;

count=count+1'b1;

end

2'b11:

beginSG=SGHH;//选中第四个管

SEL=4'b0111;

count=count+1'b1;

end

endcase

assignSELE=SEL;//设置片选信号

assignSGG=SG;//设置数码管显示信号

endmodule

 

6、多功能数字钟顶层模块设计

采用图形设计方法,将以上已经写好的各模块都选择createschematicsymbol封装成各个器件。

名字设置为complete.sch,在这个文件里将各个器件拖出来进行各引脚连线和标记输入输出端口。

由于图太小截图看不清楚,只能先给个大概如下:

其生成的vf文件如下:

//complete.vf

modulecomplete(XLXN_10,

XLXN_15,

XLXN_16,

XLXN_17,

XLXN_19,

XLXN_20,

XLXN_21,

XLXN_33,

XLXN_32,

XLXN_39,

XLXN_40);

inputXLXN_10;

inputXLXN_15;

inputXLXN_16;

inputXLXN_17;

inputXLXN_19;

inputXLXN_20;

inputXLXN_21;

inputXLXN_33;

outputXLXN_32;

output[7:

0]XLXN_39;

output[3:

0]XLXN_40;

wireXLXN_4;

wireXLXN_5;

wire[7:

0]XLXN_6;

wire[7:

0]XLXN_7;

wire[7:

0]XLXN_8;

wireXLXN_11;

wire[7:

0]XLXN_13;

wire[7:

0]XLXN_14;

wireXLXN_22;

wireXLXN_24;

wire[7:

0]XLXN_37;

wire[7:

0]XLXN_38;

freqXLXI_1(.clk(XLXN_10),

._1Hz(XLXN_24),

._1kHz(XLXN_4),

._500Hz(XLXN_5));

radioXLXI_5(.Minute(XLXN_7[7:

0]),

.Second(XLXN_8[7:

0]),

._1kHz(XLXN_4),

._500Hz(XLXN_5),

.ALARM(XLXN_11));

ringXLXI_6(.CtrRing(XLXN_21),

.Hour(XLXN_6[7:

0]),

.Minute(XLXN_7[7:

0]),

.Second(XLXN_8[7:

0]),

.SetHrkey(XLXN_19),

.SetMinkey(XLXN_20),

._1Hz(XLXN_24),

._1kHz(XLXN_4),

._500Hz(XLXN_5),

.ALARM_clock(XLXN_22),

.Set_Hr(XLXN_13[7:

0]),

.Set_Min(XLXN_14[7:

0]));

top_clockXLXI_7(.AdjHr(XLXN_16),

.AdjMin(XLXN_15),

.nCR(XLXN_17),

._1Hz(XLXN_24),

.Hour(XLXN_6[7:

0]),

.Minute(XLXN_7[7:

0]),

.Second(XLXN_8[7:

0]));

modeXLXI_8(.ALARM(XLXN_11),

.ALARM_clock(XLXN_22),

.Hour(XLXN_6[7:

0]),

.Minute(XLXN_7[7:

0]),

.mode(XLXN_33

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2