数字钟实验论文
数字钟的设计
小组成员及学号:黄婷婷15352135
黄淑桦15352134
黄蕊15352132
院系:数据科学与计算机学院
专业:移动信息工程专业
班级:1506
摘要
本设计为一个多功能的数字钟,具有时、分、秒计数显示功能,以24小时循环计数;具有校时功能。拓展实现有秒表功能,整点报时功能,倒计时功能。
本设计以硬件描述语言Verilog 为系统逻辑描述手段设计文件,利用Vivado 进行编译仿真,由各个基本模块共同构建了一个基于FPGA 的数字钟。
本实验主要经编译和仿真所设计的程序,可通过实验输出的波形图和FPGA 板子的具体操作进行验证。
关键词:数字时钟,硬件描述语言,Verilog ,FPGA
Abstract
The design for a multi-functional digital clock, with hours, minutes and seconds count display to a 24-hour cycle count; with school functions Developing stopwatch function, the whole point timekeeping function, countdown function.
This design uses the hardware description language Verilog as the system logic description method to design the document, uses Vivado to carry on the compilation simulation, by each basic module altogether constructed a FPGA based digital clock.
This experiment is mainly compiled and Simulation of the design process, through the experimental output waveform and FPGA board specific operations to verify.
Keywords :digital clock,hardware description language,Verilog ,FPGA
目录
摘要...................................................................................................... 2Abstract ................................................................................................ 3选题背景............................................................................................. 6
一,课题研究的必要性............................................................ 6二,课题研究的内容................................................................ 6三,实验可行性......................................................................... 7四,设计理念............................................................................. 9五,编程及仿真软件Vivado ..................................................... 9六,实验流程........................................................................... 10数字化时钟系统软件设计方案....................................................... 10
一,整体设计方案描述.......................................................... 10二,模块描述........................................................................... 10系统调试........................................................................................... 24
一,硬件调试.......................................................................... 24二,软件调试.......................................................................... 26实验总结........................................................................................... 26
一,实验结论.......................................................................... 26二,实验收获........................................................................... 26三,实验反思应用................................................................... 27四,实验中遇到的问题及解决方法....................................... 28
五,研究总结........................................................................... 30六,小组人员分工................................................................... 30参考文献........................................................................................... 31附录.................................................................................................... 31
一,计时的另一方法............................................................... 31
选题背景
一,课题研究的必要性
现在是一个知识爆炸的新时代。新产品、新技术层出不穷,电子技术的发展更是日新月异。可以毫不夸张的说,电子技术的应用无处不在,电子技术正在不断地改变我们的生活,改变着我们的世界。在这快速发展的年代,时间对人们来说是越来越宝贵,在快节奏的生活时,人们往往忘记了时间,一旦遇到重要的事情而忘记了时间,这将会带来很大的损失。因此我们需要一个定时系统来提醒这些忙碌的人。数字化的钟表给人们带来了极大的方便。近些年,随着科技的发展和社会的进步,人们对数字钟的要求也越来越高,传统的时钟已不能满足人们的需求。多功能数字钟不管在性能还是在样式上都发生了质的变化,有电子闹钟、数字闹钟等等。
钟表的数字化给人们生产生活带来了极大的方便,而且大大地扩展了钟表原先的报时功能。诸如定时自动报警、定时启闭电路、定时开关烘箱、通断动力设备,甚至各种定时电气的自动启用等,所有这些,都是以钟表数字化为基础的。因此,研究数字钟及扩大其应用,有着非常现实的意义。本次实验在完成时钟的基本功能后进行拓展,使其更加方便快捷,贴近生活。
二,课题研究的内容
本设计以硬件描述语言Verilog 为系统逻辑描述手段设计文件,采
用自顶向下的设计方法,由各个基本模块共同构建了一个基于FPGA 的数字钟。
本数字钟时间以24小时为一个周期, 具有时、分、秒计数显示功能。正常工作状况下显示为时分,通过调整开关改变输入电平高低,改变为显示秒界面。
本数字钟具有校时功能,可以对时、分及秒进行单独校对,使其校正到标准时间。四个按键分别控制四个需调整的位,调时位长按一秒,该位数值加一,后三位达到九后归零,最高位最大值为2,使整体及时时间不能超过23:59分。
本设计拓展实现秒表功能,通过调整开关改变输入电平高低,触发秒表功能的实现。秒表可以实现清零与暂停。
本设计拓展实现整点报时功能,无需输入,在设定的时间LED 灯进行闪烁,代替蜂鸣器。因整点时间较短,人工设定从整点开始,报时维持时间10秒。
本设计拓展实现倒计时功能,通过调整开关改变输入电平高低,进入倒计时功能。利用与校对相同的方法设定倒计时时长,通过调整开关改变输入电平高低实现暂停功能,通过按键实现重置功能。当重置时倒计时归零,如需使用需重新设定时间。暂停时,倒计时保持现有的时间不变,待再次按暂停键后,倒计时继续进行。
三,实验可行性
1,FPGA 的优越性
随着现场可编程门阵列(field program-mable gate array ,FPGA) 的出现,电子系统向集成化、大规模和高速度等方向发展的趋势更加明显,作为可编程的集成度较高的ASIC ,可在芯片级实现任意数字逻辑电路,从而可以简化硬件电路,提高系统工作速度,缩短产品研发周期。故利用FPGA 这一新的技术手段来研究电子钟有重要的现实意义。设计采用FPGA 现场可编程技术,运用自顶向下的设计思想设计电子钟。避免了硬件电路的焊接与调试,而且由于FPGA 的I /O端口丰富,内部逻辑可随意更改,使得数字电子钟的实现较为方便。2,Verilog 的优越性
本设计采用的Verilog 是一种以文本形式来描述数字系统硬件的结构和行为的硬件描述语言。
Verilog 的设计初衷是成为一种基本语法与C 语言相近的硬件描述语言,可以让电路设计人员更容易学习和接受。
Verilog 具有极强的描述能力,可以表示逻辑电路图、逻辑表达式,还可以表示数字逻辑系统所完成的逻辑功能。其能支持系统行为级、寄存器传输级和逻辑门级三个不同层次的设计;支持结构、数据流、行为三种描述形式的混合描述、覆盖面广、抽象能力强,因此在实际应用中越来越广泛。
本设计利用Verilog 结合可编程逻辑器件进行的,并通过数码管动态显示计时结果。具有易学,方便,新颖,有趣,直观,设计与实验项目成功率高,理论与实践结合紧密,体积小,容量大,I/O口丰富,易编程和加密等特点,应用非常方便。
四,设计理念
为了描述复杂的硬件电路,将复杂的功能划分为简单的功能,模块是提供每个简单功能的基本结构。
本设计采取“自顶向下”的思路,将复杂的功能模块划分为低层次的模块。自顶向下的设计方式有利于系统级别层次划分和管理,并提高了效率、降低了成本。“自底向上”方式是“自顶向下”方式的逆过程。
同时使用描述硬件的基本设计单元是模块(module )。构建复杂的电子电路,主要是通过模块的相互连接调用来实现的。模块被包含在关键字module 、endmodule 之内。实际的电路元件。Verilog 中的模块类似C 语言中的函数,它能够提供输入、输出端口,可以实例调用其他模块,也可以被其他模块实例调用。模块中可以包括组合逻辑部分、过程时序部分。
五,编程及仿真软件Vivado
Vivado 设计套件,是FPGA 厂商赛灵思公司2012年发布的集成设计环境。包括高度集成的设计环境和新一代从系统到IC 级的工具,这些均建立在共享的可扩展数据模型和通用调试环境基础上。
Vivado 工具把各类可编程技术结合在一起,能够扩展多达1亿个等效ASIC 门的设计。
六,实验流程
1. 工程师按照“自顶向下”的设计方法进行系统划分。
2. 将以上的设计输入编译成标准的Verilog 文件,并以模块形式进行封装。
3. 进行代码级的功能仿真,主要是检验系统功能设计的正确性。最后在FPGA 板子上进行实际操作。
数字化时钟系统软件设计方案
一,整体设计方案描述
设计中的数字时钟,带有按键校准,整点报时,秒表,倒计时,数码管显示等功能。整体设计代码详见附录。
二,模块描述
1,时钟模块
1.1目的
针对计时器模块与闹钟设定模块的需求,可以知道分频模块需要生成一个1Hz 的频率信号,用来产生时钟的秒脉冲,确保计时模块可以正常计数。
1.2实现代码
wire move;
wire [0:0]ss;
reg [26:0]clkdiv;
reg [23:0]times;
assign move =clkdiv[26];
assign s =clkdiv[19:18];
assign ss =clkdiv[18];
//主要实现部分
always @(posedgeclk)
begin
clkdiv
end
2,计时器模块
2.1目的
此模块除基础的计数模块外,包含了调时功能。
计数模块的作用是收到分频模块1Hz 频率的信号线,能进行正确计时,从功能上讲分别为模60计数器,模60计数器和模24计数器。校时功能,可以对时、分及秒进行单独校对,使其校正到标准时间。
2.2,实现代码
module clock(
input wire clk,
input wire mod,
input wire check,
input wire clr,
input wire [3:0]button,
output wire [1:0]s,
output reg [3:0]digit,
output wire [15:0]led
);
wire move, clk190;
wire [0:0]ss;
reg [30:0]clkdiv;
reg [23:0]times;
reg [15:0]light_reg;
assign move =clkdiv[26];
assign clk190=clkdiv[19];
assign s =clkdiv[19:18];
assign ss =clkdiv[18];
//assign times=24'b0;
always @(*)
begin
if(mod==0)
begin
case (s)
0:digit =times[11:8];
1:digit =times[15:12];
2:digit =times[19:16];
3:digit =times[23:20];
default:digit =4'b1111;
endcase
end
else if(mod==1)
begin
case (ss)
0:digit =times[3:0];
1:digit =times[7:4];
default:digit =4'b1111;
endcase
end
End
always @(posedge
begin
if(check==0)
begin move)
times[3:0]
if(times[3:0]==4'b1001)//加到10,复位
begin
times[3:0]
if(times[7:4]
else
begin
times[7:4]
times[11:8]
if(times[11:8]==4'b1001)//加到10,复位
begin
times[11:8]
if(times[15:12]
位加一
else
begin
times[15:12]
times[19:16]
if(times[19:16]==4'b1001)//加到10,复位
begin
times[19:16]
if(times[23:20]
位加一
else times[23:16]
end
end
end
end
end
end
else
begin
if(clr==0)
begin
if(button[0:0]==1)
begin
if(mod==1)
begin
if(times[3:0]==4'b1001)times[3:0]
else times[3:0]
end
else
begin
if(times[11:8]==4'b1001)times[11:8]
else times[11:8]
end
end
if(button[1:1]==1)
begin
if(mod==1)
begin times[15:12]
if(times[7:4]==4'b0101)times[7:4]
else times[7:4]
end
else
begin
if(times[15:12]==4'b0101)times[15:12]
else times[15:12]
end
end
if(button[2:2]==1)
begin
if(mod==0)
begin
if(times[19:16]==4'b0011×[23:20]==4'b0010)
times[19:16]
else if(times[19:16]==4'b1001×[23:20]==4'b0001)
times[19:16]
else
times[19:16]
end
end
if(button[3:3]==1)
begin
if(mod==0)
begin
if(times[19:16]>4'b0011×[23:20]==4'b0001)
times[23:20]
else if(times[23:20]==4'b0010)
times[23:20]
else
times[23:20]
end
end
end
else
begin
times[3:0]
times[7:4]
times[11:8]
times[15:12]
times[19:16]
times[23:20]
end
end
end
3,LED 显示模块
3.1,目的:
根据实际的需求显示计时模块的时间,还是闹钟设定模块的时间,8个七段码LED 数码管,进行扫描方式显示数据。
3.2,实现思路
本模块通过代码实现74LS48的功能,将其封装为一个模块。选择74LS48作为显示译码电路,选择数码管作为显示单元电路。计数器实现了对时间的累计并以8421BCD 码的形式输送到动态扫描模块,再由其输出的端送到74LS48,将BCD 码转换为七段码,再由数码管显示出来。
3.3,实现代码
//7seg数码管显示模块
module print(
input wire [2:0]pattern,
input wire [1:0]s,
input wire [3:0]digit,
output reg [3:0]an,
output reg [6:0]a_to_g
) ;
always @(*)
begin
an[3:0]=4'b1111;
if(pattern[0]==1&pattern[1]==0&pattern[2]==0) //显示时间的秒钟模式,只显示2位begin
if(s==0)
an[s]
if(s==1)
an[s]
end
else
an[s]
case (digit)
0:a_to_g=7'b0000001;
1:a_to_g=7'b1001111;
2:a_to_g=7'b0010010;
3:a_to_g=7'b0000110;
4:a_to_g=7'b1001100;
5:a_to_g=7'b0100100;
6:a_to_g=7'b0100000;
7:a_to_g=7'b0001111;
8:a_to_g=7'b0000000;
9:a_to_g=7'b0000100;
'hA:a_to_g=7'b0001000;
'hB:a_to_g=7'b1100000;
'hC:a_to_g=7'b0110001;
'hD:a_to_g=7'b1000010;
'hE:a_to_g=7'b0110000;
'hF:a_to_g=7'b0111000;
default:a_to_g=7'b0000001;
endcase
end
Endmodule //0
4,动态扫描模块
4.1,目的:
使每一个显示块显示与自己相对应的数据。只要保证每一位显示的时间间隔不要太大,利用人眼的视觉暂留的现象,就可以造成各位数据同时显示的假象。
4.2,实现思路
动态扫描电路将计数器输出的8421BCD 码转换为数码管需要的逻辑状态,并且输出数码管的片选信号和位选信号。所谓动态扫描显示方式是在显示某一位LED 显示块的数据的时候,让其它位不显示,然后在显示下一位的数据,同时关闭其他显示块。
4.3,实现代码
wire move, clk190;
wire [0:0]ss;
reg [30:0]clkdiv;
reg [23:0]times;
reg [15:0]light_reg;
assign move =clkdiv[26];
assign clk190=clkdiv[19];
assign s =clkdiv[19:18];
assign ss =clkdiv[18];
//assign times=24'b0;
always @(*)
begin
if(mod==0)
begin
case (s)
0:digit =times[11:8];
1:digit =times[15:12];
2:digit =times[19:16];
3:digit =times[23:20];
default:digit =4'b1111;
endcase
end
else if(mod==1)
begin
case (ss)
0:digit =times[3:0];
1:digit =times[7:4];
default:digit =4'b1111;
endcase
end
end
5,整点报时模块
5.1,目的
整点报时无需输入,在整点时间时间LED 灯进行闪烁,代替蜂鸣器。因整点时间较短,人工设定从整点开始,报时维持时间10秒。
5.2,设计说明
设计基于计数器模块
5.3,实现代码
always @(posedgeclk190)
begin
if(check==0&×[15:8]==0×[7:0]
if (light_reg==16'b[**************]0)
light_reg
else
light_reg
end
else
light_reg
end
assign led =light_reg;
endmodule
6,秒表实现模块
6.1目的
通过调整开关改变输入电平高低,触发秒表功能的实现。
6.2,实现代码
module mod10Kcnt (
input wire clr,
input wire clk,
input wire start,
output wire [1:0]s,
output reg [3:0]digit
);
reg [15:0]times;
reg [30:0]clkdiv;
wire clk190;
always @(posedgeclk)
begin
clkdiv
end
assign s=clkdiv[19:18];
assign clk190=clkdiv[19];
always @(posedgeclk190)
begin
if(start==1)
begin
if (times[3:0]==9)
begin
times[3:0]
if(times[7:4]==9)
begin
times[7:4]
if(times[11:8]==9)
begin
times[11:8]
if(times[15:12]==9)
times[15:12]
else
times[15:12]
end
else
times[11:8]
end
else
times[7:4]
end
else
times[3:0]
end
else
begin
if (clr==1)
begin
times[3:0]
times[7:4]
times[11:8]
times[15:12]
end
end
end
always @(*)
begin
case (s)
0:digit =times[3:0];
1:digit =times[7:4];
2:digit =times[11:8];
3:digit =times[15:12];
default:digit =4'b1111;
endcase
end
Endmodule
7,倒计时模块
7.1目的
通过调整开关改变输入电平高低,进入倒计时功能。利用与校对相同的方法设定倒计时时长,通过调整开关改变输入电平高低实现暂停功能,通过按键实现重置功能。当重置时倒计时归零,如需使用需重新设定时间。暂停时,倒计时保持现有的时间不变,待再次按暂停键后,倒计时继续进行。
7.2代码实现
//倒计时模块
module cut_down(
input wire clr,
input wire clk,
input wire [3:0]button,
input wire start,
output wire [1:0]s,
output reg [3:0]digit
);
reg [30:0]clkdiv;
always @(posedgeclk)
begin
clkdiv
end
reg [15:0]timex;
assign s=clkdiv[19:18];
wire move;
assign move =clkdiv[26];
always @(posedgemove)
begin
if(start==1)
begin
if(timex[3:0]!=0)timex[3:0]
else
begin
if(timex[7:4]!=0)
begin
timex[7:4]
timex[3:0]
end
else
begin
if(timex[11:8]!=0)
begin
timex[11:8]
timex[7:4]
timex[3:0]
end
else
begin
if(timex[15:12]!=0)
begin
timex[15:12]
timex[11:8]
timex[7:4]
timex[3:0]
end
end
end
end
end
else
begin
if(clr==0)
begin
if(button[0:0]==1)
begin
if(timex[3:0]==4'b1001)timex[3:0]
else timex[3:0]
end
if(button[1:1]==1)
begin
if(timex[7:4]==4'b0101)timex[7:4]
else timex[7:4]
end
if(button[2:2]==1)
begin
if(timex[11:8]==4'b1001)timex[11:8]
else timex[11:8]
end
if(button[3:3]==1)
begin
if(timex[15:12]==4'b1001)timex[15:2]
else timex[15:12]
end
end
else
begin
timex[3:0]
timex[7:4]
timex[11:8]
timex[15:12]
end
end
end
always @(*)
begin
case (s)
0:digit =timex[3:0];
1:digit =timex[7:4];
2:digit =timex[11:8];
3:digit =timex[15:12];
default:digit =4'b1111;
endcase
end
Endmodul
8顶层模块
8.1目的
调用整个设计中的各个模块,将其联系起来,完成从下到上的整合。
8.2实现代码
//顶层模块
module top (
input wire clr,
input wire clk,
input wire [2:0]pattern,
input wire [3:0]button,
input wire check,
input wire start,
output wire [3:0]an,
output wire [6:0]a_to_g,
output wire [15:0]led
);
reg [1:0]s;
wire [1:0]s_0;
wire [1:0]s_1;
wire [1:0]s_2;
reg [3:0]digit;
wire [3:0]digit_0;
wire [3:0]digit_1;
wire [3:0]digit_2;
reg clr_0,clr_1,clr_2,start_0,start_1;
reg [3:0]button_0;
reg [3:0]button_1;
always @(*)
begin
if(pattern[1]==0)
begin
if(pattern[2]==0)//显示时间
begin
clr_0
button_0
s
digit
end
else //倒计时
begin
clr_2
button_1
start_1
s
digit
end
end
else //秒表
begin
if(pattern[2]==0)
begin
clr_1
start_0
s
digit
end
end
end
clock U1(.clr(clr_0),.clk(clk),.mod(pattern[0]),.check(check),
.button(button_0),.s(s_0),.digit(digit_0),.led(led));
mod10Kcnt U2(.clr(clr_1),.clk(clk),.start(start_0),.s(s_1),.digit(digit_1));
cut_downU3(.clr(clr_2),.clk(clk),.button(button_1),
.start(start_1),.s(s_2),.digit(digit_2));
print U4(.pattern(pattern),.s(s),.digit(digit),.an(an),.a_to_g(a_to_g));
endmodule
系统调试
一,硬件调试
在软件联机调试之前,首先要确定硬件是否完全正确。检查方面主要包括:
(1)PC 机的接口和核心板上的JTAG 下载口是否连接正确;
(2)用示波器检测核心板的各个引脚是否有信号输出;
(3)LED 七段数码管显示正常
引脚分布图
FPGA 板上对应引脚:
七位数码管第一位W19
七位数码管第二位U18
七位数码管第三位T17
七位数码管第四位U17
清零T18
时分秒的切换R2
进入校时功能U16
触发秒表功能T1
秒表开始计时U17
触发倒计时功能U1
倒计时开始U17
倒计时暂停U17
二,软件调试
在确定好硬件系统正确之后,我对本设计进行分模块的软件调试。每完成一个模块就与前一个已完成的模块结合起来调试,直至实现相应功能,再编写下一模块程序。在与主程序衔接时,主程序和各子程序也需作相应的改动,以便与子程序更好的衔接,特别是显示子程序需作较大改动,以便对不同内容进行显示。
实验总结
一,实验结论
将设计程序通过波形图输出进行预估检验,通过FPGA 板进行实际操作,最终结果与预期效果基本一致,时、分、秒能够正常计数并能由控制键分别显示,整点报时功能正常,拓展功能课正常使用。二,实验收获
在此次的数字钟设计过程中,我们更进一步地熟悉有关数字电路的
知识和具体应用。学会了利用Vivado 软件进行硬件描述语言的编写,程序的仿真等工作。并能根据仿真结果分析设计的存在的问题和缺陷,从而进行程序的调试和完善。
此次的数字钟设计重在于按键的控制和各个模块代码的编写,虽然能做到各个模块的正常使用,但对于各个模块的优化设计还有一定的缺陷和不足。同时,模块划分不够清晰,导致有的模块不能多次调用,这点做的还有所不足。
硬件描述语言在一定程度上与C 语言有着紧密的联系,将其看为程序可能更加容易理解代码的含义。如将顶层模块视作main 主函数,将各个需调用的底层模块视作子函数。
总的来说,通过这次的设计实验更进一步地增强了实验的动手能力,增加了对仿真软件和硬件描述语言的理解,对数字钟的工作原理也有了更加透彻的理解。
在实验过程中,小组的合作与交流也是个及其重要的方面,集思广益分工合作,才能在有限的时间内完成这一系列设计。
三,实验反思应用
1,定时器进一步拓展
整点报时可通过比较器和调时功能转换为闹钟模式,并可以经过简单的修改,将LED 灯的变化改为电平的变化。以此可驱动接入的蜂鸣器实现声音的产生,也可将其输入到其他模块中,实现其他定时功能。例如定时开关定时自动报警、定时启闭电路、定时开关烘箱、
通断动力设备,甚至各种定时电气的自动启用等,所有这些,都可以在本基础上建构。
2,调时功能拓展
本设计中虽然有控制键对时钟进行控制,但是用到的按键太多,在实际应用上存在不足。故提出改进方案为用一个按键控制数码管的片选,再用两个按键控制计数的加减。这样可以节省按键资源,以供更多的功能的使用。
四,实验中遇到的问题及解决方法
1,计时的另一方法
本方法由案例【76】种第52例改编完成。在显示时附加毫秒的显示。通过开关控制时分,秒毫秒的切换。参考代码见附表。2,防抖模块的替换
防抖模块在整个设计中是非常必要的。一个完整的按键扫描过程还需要配合相应的键盘去抖手段才能正确的识别按键,不会发生重键和错误判断等情况。
正常思路设计应为当有按键按下时,采用软件消抖的办法去除按键抖动。模块的实现方法是先判断是否有按键按下,如有按键按下则延时一段时间,待抖动过去之后再读行线状态,如果仍有低电平行线,则确定有按键按下,然后产生一个有按键按下的信号。该模块有一个时钟输入端口,输入时钟信号是分频出来的1KHZ 的时钟;有一个输入端口与行线相连,用于输入行线状态;一个输出端口,用于输出有
按键按下的信号。由于计数脉冲为1KHZ ,故从有按键按下到输入信号产生大概需要15ms 。一旦计数完成,抖动已经过去,不会发生重键现象了,这样就去除了抖动。但本种方法在实现上有一定的难度,所以采用了通过调节频率消除抖动的方法,而未用相应的防抖模块。在这一过程中,调节一个适当的频率是非常重要的。频率过高,扫描时间过短,会导致按一次建形成多次重复计数,造成跳位;频率过低,扫描时间过长,可能导致多次按键只计数一次的情况(虽在具体实验中频率足够高未曾发生),经计算出大致范围后多次试验,频率定为0.7HZ 左右。
3,调时设置按键的思路
调时设计是很重要的一个部分,制作过程中因为防抖的困难,有想过根据其他方法进行调时的设置,如将十位开关分别分别设为0~9,该位需要调节成何种数字,便将其对应开关调至高电平输入。同时划分四位开关代表显示屏的四个七段数码管,进行要调节位的控制。但同时此方法带来的弊端为,开关使用过多,硬件有效利用率极小,因此采用了优化后未继续使用此方法。
4,模块划分不清晰
在设计电路时,对具体模块的仿真的过程中,往往没有考虑到整体设计的层面以及与上下模块接口的设计。开始按实现功能划分模块,分别做了每一个模块并进行检验,最后进行组合完成。因此,在检验每一个模块时会有起自己的一套译码模块,扫描模块,显示模块等,造成了重复的同时也为最后组合成一个大工程带来了一定的困难,
5,分频时间不是1s
时钟模块时,出现秒钟走的过快的现象。最终发现是分频程序中没有正确的对时钟脉冲信号进行正确的分频。通过在网络资源和书籍的学习正确的改善了这个问题。
五,研究总结
本次在Verilog 语言的学习上还存在一些问题,没有深入的学习,对于有些语法错误,还需要仔细的查找。同时如果将这个数字时钟应用于现实生活中,还存在些许的问题。例如按键太多,操作起来没那么的方便。在FPGA 上设计和调试都需要耐心,时钟设计在生活中无处不在,设计的过程要考虑到应用的习惯,设计更人性化的体验,才会是一个好的设计。
本设计是采用硬件描述语言和FPGA 芯片相结合进行的数字钟的研究,从中可以看出EDA 技术的发展在一定程度上实现了硬件设计的软件化。设计的过程变的相对简单,容易修改等优点,相信随着电子技术的发展,数字钟的功能会更加多样化,满足人们的各种需要。六,小组人员分工
本设计小组成员共有三人,分工如下。
黄婷婷:具体功能模块的实现;Verilog 主体代码的撰写修改。
黄淑桦:具体功能模块的实现;Verilog 代码的撰写;多重模块的总体整合;硬件测试运行。
黄蕊:前期参考资料及对应文献的查找;功能模块整体规划;实验论文的撰写。
参考文献
[1]郑利浩,赵峰等NEXYS2案例【76】2010-12-28
[2]刘君,常明,秦娟,基于硬件描述语言(VHDL )的数字时钟设计
[3]David Money Harris,Sarah L.Harris 著,陈虎等译,数字设计和计算机体系结构,机械工业出版社,2009
[4].Kawasaki Hiroaki,Sakurada Hiroshi,Narushima Shinichi, etal Double-f aced vacuum fluorescent display [P].US Patent:5463276,1995
附录
一,计时的另一方法
说明:由例52更改,自带显示扫描,译码等模块,可直接通过FPGA 板进行使用。
//例52:模-6000计数器
module mod6Kcnt (
input wire clr,
input wire clk,
output reg [13:0]q,
output wire clkm
);
reg [5:0]c;
//模-6000计数器
always @(posedgeclk or posedge clr) begin
if (clr==1)
q
else if (q==5999)
begin
q
c
end
else
q
end
assign clkm =c[0];//one minute endmodule
//例52:模-24:60计数器
module modhmcnt (
input wire clr,
input wire clk,
output reg [13:0]q
);
always @(posedgeclk or posedge clr) begin
if (clr==1)
q
else if (q[5:0]==59)
begin
q[5:0]
if (q[9:6]==24)
q[9:6]
else
q[9:6]
end
else
q
end
endmodule
//例52:时钟分频器
module clkdiv (
input wire mclk,
input wire clr,
output wire clk190,
output wire clk48
);
reg [25:0]q;
//25位计数器
always @(posedgemclk or posedge clr) begin
if (clr==1)
q
else
q
end
assign clk190=q[17];//760Hz
assign clk48=q[19];//190Hz
endmodule
//例52:14-位二进制–BCD 码转换器module binbcd14(
input wire [13:0]b,
output reg [16:0]p
);
//中间变量
reg [32:0]z;
integer i;
always @(*)
begin
for (i=0; i
z[i]=0;
z[16:3]=b; //shift b left 3places repeat (11)//重复11次
begin
if (z[17:14]>4) //如果个位大于z[17:14]=z[17:14]+3; //加3
if (z[21:18]>4) //如果十位大于z[21:18]=z[21:18]+3; //加3
if (z[25:22]>4) //如果百位大于z[25:22]=z[25:22]+3; //加3
if (z[29:26]>4) //如果千位大于z[29:26]=z[29:26]+3; //加3
z[32:1]=z[31:0];//左移一位
end
p =z[30:14];//BCD 输出
end
endmodule
//例52:x7segbc –Display 7-seg with leading blanks 4444
//输入时钟信号cclk 应为190Hz module x7segbc (
input wire [15:0]x,
input wire cclk,
input wire clr,
output reg [6:0]a_to_g,
output reg [3:0]an,
output wire dp
);
reg [1:0]s;
reg [3:0]digit;
assign dp =1; //decimal points off always @(*)
case (s)
0:digit =x[3:0];
1:digit =x[7:4];
2:digit =x[11:8];
3:digit =x[15:12];
default:digit =x[3:0];
endcase
//7段解码器:hex7seg
always @(*)
case (digit)
0:a_to_g=7'b0000001;
1:a_to_g=7'b1001111;
2:a_to_g=7'b0010010;
3:a_to_g=7'b0000110;
4:a_to_g=7'b1001100;
5:a_to_g=7'b0100100;
6:a_to_g=7'b0100000;
7:a_to_g=7'b0001111;
8:a_to_g=7'b0000000;
9:a_to_g=7'b0000100;
'hA:a_to_g=7'b0001000;
'hB:a_to_g=7'b1100000;
'hC:a_to_g=7'b0110001;
'hD:a_to_g=7'b1000010;
'hE:a_to_g=7'b0110000;
'hF:a_to_g=7'b0111000;
default:a_to_g=7'b0000001; //0endcase
//数字选择
always @(*)
begin
an =4'b1111;
//if(aen[s]==1)
an[s]=0;
end
//2-位计数器
always @(posedgecclk or posedge clr) begin
if (clr==1)
s
else
s
end
endmodule
//例52:模-10,000计数器module mod10Kcnt_top(
input wire mclk,
input wire [3:3]btn,
input wire [3:3]sw,
output wire [6:0]a_to_g,
output wire [3:0]an,
output wire dp
);
wire [16:0]p;
wire clr, show, clk48, clk190, clkm; wire [13:0]b1;
wire [13:0]b2;
reg [13:0]b;
assign clr =btn[3];
assign show =sw[3];
clkdiv U1(.mclk(mclk),
.clr(clr),
.clk190(clk190),
.clk48(clk48)
);
mod6Kcnt U2(.clr(clr),
.clk(clk48),
.q(b1),
.clkm(clkm)
);
modhmcnt U3(.clr(clr),
.clk(clkm),
.q(b2)
);
always @(*) begin
if(show==1)
b[13:0]
b[13:0]
binbcd14U4(.b(b),
.p(p)
);
x7segbc U5(.x(p[15:0]),.cclk(clk190),.clr(clr),
.a_to_g(a_to_g),.an(an),
.dp(dp)
);
endmodule