数字时钟报告.docx
《数字时钟报告.docx》由会员分享,可在线阅读,更多相关《数字时钟报告.docx(13页珍藏版)》请在冰豆网上搜索。
![数字时钟报告.docx](https://file1.bdocx.com/fileroot1/2022-11/27/c73477ea-7122-477c-a58b-9ac80dabecce/c73477ea-7122-477c-a58b-9ac80dabecce1.gif)
数字时钟报告
EDA设计课程实验报告
实验题目:
数字时钟
学院名称:
专业:
班级:
姓名:
高胜学号
小组成员:
指导教师:
一、实验目的
学习数字时钟的设计原理。
二、设计任务及要求
利用QuartusII软件设计一个数字钟,对设计电路进行功能仿真,并下载到SmartSOPC实验系统中,可以完成00-00-00到23-59-59的计时功能,并在控制电路的作用下具有保持和清零功能,做到能够创新的添加自己能够实现的功能,例如快速校时、快速校分、整点报时等。
三、系统设计
1、整体设计方案
一个完整的时钟应由3部分组成:
秒脉冲发生电路、计数显示部分和时钟调整部分。
一个时钟的准确与否主要取决秒脉冲的准确度。
为了保证计时准确,对系统时钟48MHz进行了48000000分频,从而得到1Hz的秒脉冲。
数字计钟是由秒脉冲发生电路、计数显示部分和时钟调整这3个部分基本电路组成的。
数字计钟的系统框图(见图1):
图1数字计钟的系统框图
2、功能模块电路设计
秒脉冲发生电路将分频后的脉冲输入,时钟调整电路进行响应,使数码管显示**-**-**的时间格式,并且每次脉冲使数码管实现计时功能,从00-00-00计时到23-59-59.
(1)系统模块框图(见图2)
图2系统模块框图
(2)模块逻辑表达
数码管选择真值表(见表一):
表一选择数码管真值表
数码管显示位真值表(见表二):
表二数码管显示位真值表
译码真值表(见表三):
表三译码真值表
(3)算法流程图(见图3)
N
Y
图3算法流程图
(4)Verilog源代码
moduleclock(clk,key,dig,seg);//模块名clock
inputclk;//输入时钟
input[1:
0]key;//输入按键
output[7:
0]dig;//数码管选择输出引脚
output[7:
0]seg;//数码管段输出引脚
reg[7:
0]seg_r;//定义数码管输出寄存器
reg[7:
0]dig_r;//定义数码管选择输出寄存器
reg[3:
0]disp_dat;//定义显示数据寄存器
reg[24:
0]count;//定义计数寄存器
reg[23:
0]hour;//定义现在时刻寄存器
regsec,keyen;//定义标志位
reg[1:
0]dout1,dout2,dout3;//寄存器
wire[1:
0]key_done;//按键消抖输出
assigndig=dig_r;//输出数码管选择
assignseg=seg_r;//输出数码管译码结果
//秒信号产生部分
always@(posedgeclk)//定义clock上升沿触发
begin
count=count+1'b1;
if(count==25'd24000000)//0.5S到了吗?
begin
count=25'd0;//计数器清零
sec=~sec;//置位秒标志
end
end
//按键消抖处理部分
assignkey_done=(dout1|dout2|dout3);//按键消抖输出
always@(posedgecount[17])
begin
dout1<=key;
dout2<=dout1;
dout3<=dout2;
end
always@(negedgekey_done[0])
begin
keyen=~keyen;//将琴键开关转换为乒乓开关
end
//数码管动态扫描显示部分
always@(posedgeclk)//count[17:
15]大约1ms改变一次
begin
case(count[17:
15])//选择扫描显示数据
3'd0:
disp_dat=hour[3:
0];//秒个位
3'd1:
disp_dat=hour[7:
4];//秒十位
3'd2:
disp_dat=4'ha;//显示"-"
3'd3:
disp_dat=hour[11:
8];//分个位
3'd4:
disp_dat=hour[15:
12];//分十位
3'd5:
disp_dat=4'ha;//显示"-"
3'd6:
disp_dat=hour[19:
16];//时个位
3'd7:
disp_dat=hour[23:
20];//时十位
endcase
case(count[17:
15])//选择数码管显示位
3'd0:
dig_r=8'b11111110;//选择第一个数码管显示
3'd1:
dig_r=8'b11111101;//选择第二个数码管显示
3'd2:
dig_r=8'b11111011;//选择第三个数码管显示
3'd3:
dig_r=8'b11110111;//选择第四个数码管显示
3'd4:
dig_r=8'b11101111;//选择第五个数码管显示
3'd5:
dig_r=8'b11011111;//选择第六个数码管显示
3'd6:
dig_r=8'b10111111;//选择第七个数码管显示
3'd7:
dig_r=8'b01111111;//选择第八个数码管显示
endcase
end
always@(posedgeclk)
begin
case(disp_dat)
4'h0:
seg_r=8'hc0;//显示0
4'h1:
seg_r=8'hf9;//显示1
4'h2:
seg_r=8'ha4;//显示2
4'h3:
seg_r=8'hb0;//显示3
4'h4:
seg_r=8'h99;//显示4
4'h5:
seg_r=8'h92;//显示5
4'h6:
seg_r=8'h82;//显示6
4'h7:
seg_r=8'hf8;//显示7
4'h8:
seg_r=8'h80;//显示8
4'h9:
seg_r=8'h90;//显示9
4'ha:
seg_r=8'hbf;//显示-
default:
seg_r=8'hff;//不显示
endcase
if((count[17:
15]==3'd2)&sec)
seg_r=8'hff;
end
//计时处理部分
always@(negedgesecornegedgekey_done[1])//计时处理
begin
if(!
key_done[1])//是清零键吗?
begin
hour=24'h0;//是,则清零
end
elseif(!
keyen)
begin
hour[3:
0]=hour[3:
0]+1'b1;//秒加1
if(hour[3:
0]==4'ha)
begin
hour[3:
0]=4'h0;
hour[7:
4]=hour[7:
4]+1'b1;//秒的十位加一
if(hour[7:
4]==4'h6)
begin
hour[7:
4]=4'h0;
hour[11:
8]=hour[11:
8]+1'b1;//分个位加一
if(hour[11:
8]==4'ha)
begin
hour[11:
8]=4'h0;
hour[15:
12]=hour[15:
12]+1'b1;//分十位加一
if(hour[15:
12]==4'h6)
begin
hour[15:
12]=4'h0;
hour[19:
16]=hour[19:
16]+1'b1;//时个位加一
if(hour[19:
16]==4'ha)
begin
hour[19:
16]=4'h0;
hour[23:
20]=hour[23:
20]+1'b1;//时十位加一
end
if(hour[23:
16]==8'h24)
hour[23:
16]=8'h0;
end
end
end
end
end
end
endmodule
四、系统调试
1、仿真调试
(1)仿真代码
位码代码仿真:
`timescale1ns/1ns
modulesmg_tp;//测试模块的名字
reg[2:
0]c;//测试输入信号定义为reg型
wire[7:
0]dig;//测试输出信号定义为wire型
parameterDELY=100;//延时100秒
weiu1(c,dig);//调用测试对象
initialbegin//激励波形设定
c=3'b0;
#DELYc=3'b001;
#DELYc=3'b010;
#DELYc=3'b100;
#DELYc=3'b101;
#DELYc=3'b110;
#DELYc=3'b111;
#DELY$finish;
end
initial$monitor($time,,,"dig=%d,c=%b",dig,c);//输出格式i定义
endmodule
modulewei(c,dig);//命名模块名字
input[2:
0]c;
output[7:
0]dig;//定义输入与输出
reg[7:
0]dig_r;
reg[2:
0]c_r;//定义dig_r与c_r2个reg型数据
assigndig=dig_r;//将reg型数据转化为wire型数据
always@(*)//检测c_r的数据是否变化
beginc_r=c;
case(c_r)
3'b000:
dig_r=8'b11111110;//c_r的数据变化而dig_r对于的数据变化
3'b001:
dig_r=8'b11111101;
3'b010:
dig_r=8'b11111011;
3'b011:
dig_r=8'b11110111;
3'b100:
dig_r=8'b11101111;
3'b101:
dig_r=8'b11011111;
3'b110:
dig_r=8'b10111111;
3'b111:
dig_r=8'b01111111;
default:
dig_r=8'b11111111;
endcase//结束case语句
end//结束always语句
endmodule//结束程序
译码器代码仿真:
`timescale1ns/1ns
moduleduan_tp;//测试模块的名字
reg[3:
0]a;//测试输入信号定义为reg型
wire[7:
0]seg;//测试输出信号定义为wire型
parameterDELY=100;//延时100秒
duanu1(a,seg);//调用测试对象
initialbegin//激励波形设定
a=4'b0;
#DELYa=4'b0001;
#DELYa=4'b0010;
#DELYa=4'b0011;
#DELYa=4'b0100;
#DELYa=4'b0101;
#DELYa=4'b0110;
#DELYa=4'b0111;
#DELYa=4'b1000;
#DELYa=4'b1001;
#DELYa=4'b1010;
#DELYa=4'b1011;
#DELYa=4'b1100;
#DELYa=4'b1101;
#DELYa=4'b1110;
#DELYa=4'b1111;
#DELY$finish;
end
initial$monitor($time,,,"seg=%d,a=%b",seg,a);//输出格式i定义
endmodule
moduleduan(a,seg);//命名模块名字
input[3:
0]a;
output[7:
0]seg;//定义输入与输出
reg[7:
0]seg_r;
reg[3:
0]a_r;//定义seg_r与a_r2个reg型数据
assignseg=seg_r;//将reg型数据转化为wire型数据
always@(*)//检测c_r的数据是否变化
begina_r=a;
case(a_r)//七段译码
4'b0000:
seg_r=8'hc0;//显示0
4'b0001:
seg_r=8'hf9;//显示1
4'b0010:
seg_r=8'ha4;//显示2
4'b0011:
seg_r=8'hb0;//显示3
4'b0100:
seg_r=8'h99;//显示4
4'b0101:
seg_r=8'h92;//显示5
4'b0110:
seg_r=8'h82;//显示6
4'b0111:
seg_r=8'hf8;//显示7
4'b1000:
seg_r=8'h80;///显示8
4'b1001:
seg_r=8'h90;//显示9
4'b1010:
seg_r=8'h88;//显示a
4'b1011:
seg_r=8'h83;//显示b
4'b1100:
seg_r=8'hc6;//显示c
4'b1101:
seg_r=8'ha1;//显示d
4'b1110:
seg_r=8'h86;//显示e
4'b1111:
seg_r=8'h8e;///显示f
endcase//结束case语句
end//结束always语句
endmodule//结束程序
(3)仿真波形图
位码代码仿真图(见图4)
图4位码代码仿真波形
译码器代码仿真图(见图5)
图5译码器代码仿真波形
3.波形分析
从仿真图可以看出程序是正确的。
2、实际调试
(1)测试条件、管脚分配
引脚分配(见图6)
图6管脚分配图
(2)测试结果及数据
实验箱运行开始运行时数码管显示00-00-00,并且在之后开始计时,同时数码管显示开始变化00-00-01,00-00-02,......。
五、实验感想