注意
本实验代码为初学FPGA所写,逻辑不太清晰,请跳往下面网址查看最新的模块化设计数字钟,更易看懂
模块化多功能数字钟设计
前言:
本文主要介绍了EDA原理与应用这门课程的相关实验及代码。使用的软件是Quartus Ⅱ,该实验使用fpga芯片为cycloneⅤ 5CSEMA5F31C6。
(一)实验目的
(1)了解数字钟的工作原理;
(2)掌握综合且较复杂数字系统设计方法;
(3)掌握多层次、多模块数字系统设计方法。
(二)设计要求
设计一个多功能数字钟:
(1)数码管显示时、分、秒;
(2)具有正常计时和调时、调分等校时功能;
(3) 经设置应具有整点报时功能(在59分56秒后开始报时,并用一串LED管显示);
(4)经设置应具有闹钟功能(用LED管点亮表示,时间为一分钟)。
其他扩展功能自行设置。
分析:
时分秒的计数器的时钟信号要前置一个选择模块,用于选择时种来源,即正常的计数时钟及调节时钟,以及一个允许/禁止输入用于控制是否输出时钟信号。
为提高计时准确度,秒的计数脉冲由外电路分频为0.1秒后由调节模块处理;
调节模块处理包含一个前置的模10计数器,用于将生成0.1秒的调节脉冲和1秒的计时脉冲。工作与否由调节模块的调节输入决定;
调节模块处理还包含一个模5计数器,用于当数字钟处于调节状态下,监测调节键按下的时间。调节键按下时允许0.1秒计数脉冲作用,否则以键按下产生的脉冲作为计数脉冲。调节按键没有被按下时,停止;
驱动数码管显示需要的bcd-7段显示码译码器;
功能键每按下恢复时,产生秒-分钟-小时-计时的切换,同一时间只允许其中之一的计数器使能计数,并且通过对调节模块的控制,改变时钟信号。文章来源:https://www.toymoban.com/news/detail-464547.html
(三)实验代码
/*
mode
mb
计时
st-->开始计时(1)-->暂停计时(0)-->开始计时...
rst-暂停计时时-->归零
en
0 时间显示
小时:0-23
分钟:0-59
秒:0-59
1 闹钟设置
st--加1(默认分钟)
rd--减1
rst--切换小时/分钟设置 默认分钟-->小时-->分钟
小时:0-23
分钟:0-59
mode-->返回时间显示(按过st,rst)
2 时间设置
st--
秒(默认)-->归0
分钟/分钟-->+1
rd--
秒(默认)-->归0
分钟/分钟-->+1
rst-->
秒-->分钟-->小时
mode-->返回时间显示(按过st,rst)
*/
module clock(
input clk1,en,clr,mb,
input mode_an,st_an,rd_an,rst_an,//功能键,显示日期/加,减,预设闹钟时间/调整位置
output reg clk,
output reg [2:0] mode, //功能
output reg [5:0] shi,fen,miao, //储存时分秒
output reg [5:0] jss,jsf,jsm, //储存计时
output reg [5:0] nzs,nzf,nzjs, //闹钟时,分,闹钟计时
output reg zddis,nzdis, //整点报时,闹钟显示
output reg [6:0] SG0,SG1,SG2,SG3,SG4,SG5 //数码管的值
);
//wire !mode_an,!st_an,!rd_an,!rst_an; //按键 按下--1
reg [5:0] rtmode; //返回时间显示界面
reg js; //计时设置时情况 1-开始计时,0-暂停
reg nz; //闹钟设置情况 1-小时,0-分钟
reg [1:0]sj; //时间设置情况 2-小时,1-分钟,0-秒
wire [3:0] miaog,miaos,feng,fens,shig,shis; //数码管显示时间
wire [3:0] jsmg,jsms,jsfg,jsfs,jssg,jsss; //数码管显示计时
wire [3:0] nzfg,nzfs,nzsg,nzss; //数码管显 示闹钟
reg [30:0] cnt;
always @(posedge clk1)
if(mb)
begin cnt=cnt+1;
if(cnt>10)
begin clk=1'b1;cnt=0; end
else clk=1'b0;
end
else if(en)
begin cnt=cnt+1;
if(cnt>1)
begin clk=1'b0;cnt=0; end
else clk=1'b1;
end
always @(posedge clk or posedge clr)
begin
if(clr)
begin
mode<=0;
shi<=23;fen<=59;miao<=56; sj<=0;
jss<=0;jsf<=0;jsm<=0;js<=0;
nzs<=0;nzf<=0;nz<=0;
end
else if(mb)
begin
begin
if(!st_an) //按下st,开始计时,再按下暂停计时。。
begin
js<=js+1;
if(js==1)
js<=0;
end
begin
case(js)
0: //暂停时间
begin
if(!rst_an) //按下rst置0
begin
jsm<=0;jsf<=0;jss<=0;
end
end
1://开始计时
begin
jsm<=jsm+1;
if(jsm==99)
begin
jsf<=jsf+1;jsm<=0;
if(jsf==59)
begin
jss<=jss+1;jsf<=0;
if(jss==59)
begin jss<=0; end
end
end
end
default: begin jsm<=0;jsf<=0;jss<=0;end
endcase
end
end
end
else if(en)
begin
if(!mode_an)
begin
mode<=mode+1;
if(mode==3)
mode<=0;
end
case(mode)
0://时间显示
begin
miao<=miao+1;
if(miao==59)
begin
fen<=fen+1;miao<=0;
if(fen==59)
begin
shi<=shi+1;fen<=0;
if(shi==23)
begin shi<=0; end
end
end
end
1://闹钟设置
begin
miao<=miao+1;
if(miao==59)
begin
fen<=fen+1;miao<=0;
if(fen==59)
begin
shi<=shi+1;fen<=0;
if(shi==23)
begin shi<=0; end
end
end
if(!rst_an) //切换小时/分钟,默认分钟-小时(第一次按下rst)
begin
nz<=nz+1;
rtmode<=rtmode+1;
if(nz==1)
nz<=0;
end
begin
case(nz)
0: //调节闹钟分钟
begin
if(!st_an) //按下st,+1
begin
rtmode<=rtmode+1;
nzf<=nzf+1;
if(nzf==59)
nzf<=0;
end
if(!rd_an) //按下rd,-1
begin
rtmode<=rtmode+1;
nzf<=nzf-1;
if(nzf==0)
nzf<=59;
end
end
1: //调节闹钟小时
begin
if(!st_an) //按下st,+1
begin
rtmode<=rtmode+1;
nzs<=nzs+1;
if(nzs==23)
nzs<=0;
end
if(!rd_an) //按下rd,-1
begin
rtmode<=rtmode+1;
nzs<=nzs-1;
if(nzs==0)
nzs<=23;
end
end
default: begin nzf<=0;nzs<=0; end
endcase
end
if(rtmode!=0&&!mode_an) //按下mode返回时间显示
begin mode<=0;rtmode<=0;nz<=0; end
end
2://时间设置
begin
if(!rst_an) //秒(默认)/分钟/小时
begin
sj<=sj+1;
rtmode<=rtmode+1;
if(sj==2)
sj<=0;
end
begin
case(sj)
0: //秒
begin
if(!st_an) //重置
begin
rtmode<=rtmode+1;
miao<=0;
end
end
1: //分
begin
if(!st_an) //+1
begin
rtmode<=rtmode+1;
fen<=fen+1;
if(fen==59)
fen<=0;
end
if(!rd_an) //-1
begin
rtmode<=rtmode+1;
fen<=fen-1;
if(fen==0)
fen<=59;
end
end
2: //小时
begin
if(!st_an) //+1
begin
rtmode<=rtmode+1;
shi<=shi+1;
if(shi==23)
shi<=0;
end
if(!rd_an) //-1
begin
rtmode<=rtmode+1;
shi<=shi-1;
if(shi==0)
shi<=23;
end
end
default: begin shi<=0;fen<=0;miao<=0;end
endcase
end
if(rtmode!=0&&!mode_an) //按下mode返回时间显示
begin mode<=0;rtmode<=0;sj<=0; end
end
endcase
end
end
//整点报时
always @(negedge clk)
begin
if(mode==0) //时间显示时才报时
begin
if(fen==0&&miao==0)
zddis<=1;
else
zddis<=0;
end
end
//闹钟
always @(negedge clk)
begin
if(mode==0) //时间显示时闹钟才启动
begin
if(fen==nzf&&shi==nzs)
begin
nzdis<=1;nzjs<=nzjs+1;
if(nzjs==59)
begin nzdis<=0;nzjs<=0; end
end
else if(fen!=nzf||shi!=nzs)
begin nzdis<=0;nzjs<=0; end
end
end
assign miaos=miao/10;assign miaog=miao%10;assign fens=fen/10;assign feng=fen%10;assign shis=shi/10;assign shig=shi%10;
assign jsms=jsm/10;assign jsmg=jsm%10;assign jsfs=jsf/10;assign jsfg=jsf%10;assign jsss=jss/10;assign jssg=jss%10;
assign nzss=nzs/10;assign nzsg=nzs%10;assign nzfs=nzf/10;assign nzfg=nzf%10;
always @(negedge clk)
begin
if(mb)
begin
case(jsmg)
0:SG0<=7'b1000000; 1:SG0<=7'b1111001;
2:SG0<=7'b0100100; 3:SG0<=7'b0110000;
4:SG0<=7'b0011001; 5:SG0<=7'b0010010;
6:SG0<=7'b0000010; 7:SG0<=7'b1111000;
8:SG0<=7'b0000000; 9:SG0<=7'b0010000; //7段译码值
endcase
case(jsms)
0:SG1<=7'b1000000; 1:SG1<=7'b1111001;
2:SG1<=7'b0100100; 3:SG1<=7'b0110000;
4:SG1<=7'b0011001; 5:SG1<=7'b0010010;
6:SG1<=7'b0000010; 7:SG1<=7'b1111000;
8:SG1<=7'b0000000; 9:SG1<=7'b0010000; //7段译码值
endcase
case(jsfg)
0:SG2<=7'b1000000; 1:SG2<=7'b1111001;
2:SG2<=7'b0100100; 3:SG2<=7'b0110000;
4:SG2<=7'b0011001; 5:SG2<=7'b0010010;
6:SG2<=7'b0000010; 7:SG2<=7'b1111000;
8:SG2<=7'b0000000; 9:SG2<=7'b0010000; //7段译码值
endcase
case(jsfs)
0:SG3<=7'b1000000; 1:SG3<=7'b1111001;
2:SG3<=7'b0100100; 3:SG3<=7'b0110000;
4:SG3<=7'b0011001; 5:SG3<=7'b0010010;
6:SG3<=7'b0000010; 7:SG3<=7'b1111000;
8:SG3<=7'b0000000; 9:SG3<=7'b0010000; //7段译码值
endcase
case(jssg)
0:SG4<=7'b1000000; 1:SG4<=7'b1111001;
2:SG4<=7'b0100100; 3:SG4<=7'b0110000;
4:SG4<=7'b0011001; 5:SG4<=7'b0010010;
6:SG4<=7'b0000010; 7:SG4<=7'b1111000;
8:SG4<=7'b0000000; 9:SG4<=7'b0010000; //7段译码值
endcase
case(jsss)
0:SG5<=7'b1000000; 1:SG5<=7'b1111001;
2:SG5<=7'b0100100; 3:SG5<=7'b0110000;
4:SG5<=7'b0011001; 5:SG5<=7'b0010010;
6:SG5<=7'b0000010; 7:SG5<=7'b1111000;
8:SG5<=7'b0000000; 9:SG5<=7'b0010000; //7段译码值
endcase
end
else if(en)
case(mode)
0: //显示时间
begin
case(miaog)
0:SG0<=7'b1000000; 1:SG0<=7'b1111001;
2:SG0<=7'b0100100; 3:SG0<=7'b0110000;
4:SG0<=7'b0011001; 5:SG0<=7'b0010010;
6:SG0<=7'b0000010; 7:SG0<=7'b1111000;
8:SG0<=7'b0000000; 9:SG0<=7'b0010000; //7段译码值
default: SG0<=7'b1111111;
endcase
case(miaos)
0:SG1<=7'b1000000; 1:SG1<=7'b1111001;
2:SG1<=7'b0100100; 3:SG1<=7'b0110000;
4:SG1<=7'b0011001; 5:SG1<=7'b0010010;
6:SG1<=7'b0000010; 7:SG1<=7'b1111000;
8:SG1<=7'b0000000; 9:SG1<=7'b0010000; //7段译码值
default: SG1<=7'b1111111;
endcase
case(feng)
0:SG2<=7'b1000000; 1:SG2<=7'b1111001;
2:SG2<=7'b0100100; 3:SG2<=7'b0110000;
4:SG2<=7'b0011001; 5:SG2<=7'b0010010;
6:SG2<=7'b0000010; 7:SG2<=7'b1111000;
8:SG2<=7'b0000000; 9:SG2<=7'b0010000; //7段译码值
endcase
case(fens)
0:SG3<=7'b1000000; 1:SG3<=7'b1111001;
2:SG3<=7'b0100100; 3:SG3<=7'b0110000;
4:SG3<=7'b0011001; 5:SG3<=7'b0010010;
6:SG3<=7'b0000010; 7:SG3<=7'b1111000;
8:SG3<=7'b0000000; 9:SG3<=7'b0010000; //7段译码值
endcase
case(shig)
0:SG4<=7'b1000000; 1:SG4<=7'b1111001;
2:SG4<=7'b0100100; 3:SG4<=7'b0110000;
4:SG4<=7'b0011001; 5:SG4<=7'b0010010;
6:SG4<=7'b0000010; 7:SG4<=7'b1111000;
8:SG4<=7'b0000000; 9:SG4<=7'b0010000; //7段译码值
endcase
case(shis)
0:SG5<=7'b1000000; 1:SG5<=7'b1111001;
2:SG5<=7'b0100100; 3:SG5<=7'b0110000;
4:SG5<=7'b0011001; 5:SG5<=7'b0010010;
6:SG5<=7'b0000010; 7:SG5<=7'b1111000;
8:SG5<=7'b0000000; 9:SG5<=7'b0010000; //7段译码值
endcase
end
1://闹钟显示
begin
case(nzfg)
0:SG0<=7'b1000000; 1:SG0<=7'b1111001;
2:SG0<=7'b0100100; 3:SG0<=7'b0110000;
4:SG0<=7'b0011001; 5:SG0<=7'b0010010;
6:SG0<=7'b0000010; 7:SG0<=7'b1111000;
8:SG0<=7'b0000000; 9:SG0<=7'b0010000; //7段译码值
endcase
case(nzfs)
0:SG1<=7'b1000000; 1:SG1<=7'b1111001;
2:SG1<=7'b0100100; 3:SG1<=7'b0110000;
4:SG1<=7'b0011001; 5:SG1<=7'b0010010;
6:SG1<=7'b0000010; 7:SG1<=7'b1111000;
8:SG1<=7'b0000000; 9:SG1<=7'b0010000; //7段译码值
endcase
case(nzsg)
0:SG2<=7'b1000000; 1:SG2<=7'b1111001;
2:SG2<=7'b0100100; 3:SG2<=7'b0110000;
4:SG2<=7'b0011001; 5:SG2<=7'b0010010;
6:SG2<=7'b0000010; 7:SG2<=7'b1111000;
8:SG2<=7'b0000000; 9:SG2<=7'b0010000; //7段译码值
endcase
case(nzss)
0:SG3<=7'b1000000; 1:SG3<=7'b1111001;
2:SG3<=7'b0100100; 3:SG3<=7'b0110000;
4:SG3<=7'b0011001; 5:SG3<=7'b0010010;
6:SG3<=7'b0000010; 7:SG3<=7'b1111000;
8:SG3<=7'b0000000; 9:SG3<=7'b0010000; //7段译码值
endcase
SG4<=7'b1111111;SG5<=7'b1111111;
end
2: //时间显示
begin
case(miaog)
0:SG0<=7'b1000000; 1:SG0<=7'b1111001;
2:SG0<=7'b0100100; 3:SG0<=7'b0110000;
4:SG0<=7'b0011001; 5:SG0<=7'b0010010;
6:SG0<=7'b0000010; 7:SG0<=7'b1111000;
8:SG0<=7'b0000000; 9:SG0<=7'b0010000; //7段译码值
default: SG0<=7'b1111111;
endcase
case(miaos)
0:SG1<=7'b1000000; 1:SG1<=7'b1111001;
2:SG1<=7'b0100100; 3:SG1<=7'b0110000;
4:SG1<=7'b0011001; 5:SG1<=7'b0010010;
6:SG1<=7'b0000010; 7:SG1<=7'b1111000;
8:SG1<=7'b0000000; 9:SG1<=7'b0010000; //7段译码值
default: SG1<=7'b1111111;
endcase
case(feng)
0:SG2<=7'b1000000; 1:SG2<=7'b1111001;
2:SG2<=7'b0100100; 3:SG2<=7'b0110000;
4:SG2<=7'b0011001; 5:SG2<=7'b0010010;
6:SG2<=7'b0000010; 7:SG2<=7'b1111000;
8:SG2<=7'b0000000; 9:SG2<=7'b0010000; //7段译码值
endcase
case(fens)
0:SG3<=7'b1000000; 1:SG3<=7'b1111001;
2:SG3<=7'b0100100; 3:SG3<=7'b0110000;
4:SG3<=7'b0011001; 5:SG3<=7'b0010010;
6:SG3<=7'b0000010; 7:SG3<=7'b1111000;
8:SG3<=7'b0000000; 9:SG3<=7'b0010000; //7段译码值
endcase
case(shig)
0:SG4<=7'b1000000; 1:SG4<=7'b1111001;
2:SG4<=7'b0100100; 3:SG4<=7'b0110000;
4:SG4<=7'b0011001; 5:SG4<=7'b0010010;
6:SG4<=7'b0000010; 7:SG4<=7'b1111000;
8:SG4<=7'b0000000; 9:SG4<=7'b0010000; //7段译码值
endcase
case(shis)
0:SG5<=7'b1000000; 1:SG5<=7'b1111001;
2:SG5<=7'b0100100; 3:SG5<=7'b0110000;
4:SG5<=7'b0011001; 5:SG5<=7'b0010010;
6:SG5<=7'b0000010; 7:SG5<=7'b1111000;
8:SG5<=7'b0000000; 9:SG5<=7'b0010000; //7段译码值
endcase
end
endcase
end
endmodule
(四)管脚分配
Input
clk1 AF14 en AC12
Clr AB12 mb AF9
mode_an,st_an,rd_an,rst_an 按键3-1
Output
SG0,SG1,SG2,SG3,SG4,SG5 数码管0-5
zddis,nzdis, led9-8文章来源地址https://www.toymoban.com/news/detail-464547.html
到了这里,关于EDA实验(Quartus Ⅱ+fpga) (五)---多功能数字钟设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!