您好,欢迎来到东饰资讯网。
搜索
您的当前位置:首页基于FPGA的多功能数字钟设计实现

基于FPGA的多功能数字钟设计实现

来源:东饰资讯网


电子技术课程设计

设计报告

题班

目级

: 基于FPGA的多功能数字钟设计实现 :

姓 名 :

学 号 :

指导教师:

上交日期: 2017.5.21

1

摘 要

本设计为基于FPGA的多功能数字钟设计实现,具有计时、校对、闹钟、报整点等基础功能,以及日期、秒表、电子琴、延时闹钟、音乐闹钟等拓展功能。

本设计采用EDA技术,以硬件描述语言Verilog HDL为系统逻辑描述语言设计文件,在QUARTUSII工具软件环境下,采用自顶向下的设计方法,由各个基本模块共同构建了一个基于FPGA的数字钟。

系统采用Alera DE0开发板,并外接了蜂鸣器电路。系统由分频模块、计时模块、闹钟模块、控制模块、显示模块、秒表模块、音乐模块、日期模块、电子琴模块组成。经编译和仿真所设计的程序,在可编程逻辑器件上下载验证,本系统能够完成需求功能。

关键词:数字时钟,硬件描述语言,Verilog HDL,FPGA

2

目录

摘 要............................................................................................................................ 2 目录................................................................................................................................ 3 1 绪论 ........................................................................................................................... 5

1.1 背景 .............................................................................................................. 5 1.2 项目创意 ...................................................................................................... 7 2

需求分析................................................................................................................. 8 2.1 任务目标 ...................................................................................................... 8 2.2 元件清单 ...................................................................................................... 8 2.3小组分工 ......................................................................................................... 9 3系统设计 .................................................................................................................... 9

3.1 系统主板电路分析 ........................................................................................ 9 3.2模块化设计方案 ........................................................................................... 16 4 模块电路设计 ......................................................................................................... 17

4.1顶层模块 ....................................................................................................... 17 4.2分频模块 ....................................................................................................... 19

4.2.1 分频模块设计 ................................................................................... 19 4.2.2 分频模块仿真 ................................................................................... 21 4.3 计时模块 ...................................................................................................... 21

4.3.1 计时模块设计 ................................................................................... 21 4.3.2 计时模块仿真 ................................................................................... 23 4.4 控制模块 ...................................................................................................... 24

4.4.1 控制模块设计 ................................................................................... 24 4.4.2 控制模块仿真 ................................................................................... 24 4.5 秒表模块 ...................................................................................................... 24

4.5.1 秒表模块设计 ................................................................................... 24 4.6 日期模块 ...................................................................................................... 26

4.6.1 日期模块设计 ................................................................................... 26 4.7 电子琴模块 .................................................................................................. 28

3

4.7.1 电子琴模块设计 ............................................................................... 28

5 系统调试及结果分析 ............................................................................................. 30

5.1 硬件检查 ...................................................................................................... 30 5.2 软件编译 ...................................................................................................... 30 5.3 调试过程及结果 .......................................................................................... 31 5.4 调试注意事项 .............................................................................................. 32 6 总结 ......................................................................................................................... 33

6.1课设中出现的问题与解决方案 ................................................................... 33 6.2心得体会 ....................................................................................................... 33

4

1 绪论

1.1 背景

现代的社会是一个信息产品广泛使用,产品的性能越来越强大,做工越来越精细,工艺越来越高,更新换代越来越迅速的社会。而支持电子信息产品高速发展的是不断提高的微电子制造工艺水平和不断发展的电子产品的设计开发技术。EDA技术则正是为了适应现代电子技术的要求,吸收众多学科最新科技成果而形成的一门新技术。

EDA是电子设计自动化(Electronics Design Automation)的缩写,在20世纪60年代中期从计算机辅助设计(CAD)、计算机辅助制造(CAM)、计算机辅助测试(CAT)和计算机辅助工程(CAE)的概念发展而来的。EDA技术就是以计算机为工具,设计者在EDA软件平台上,用硬件描述语言VerilogHDL完成设计文件,然后由计算机自动地完成逻辑编译、化简、分割、综合、优化、布局、布线和仿真,直至对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。EDA技术的出现,极大地提高了电路设计的效率和可操作性,减轻了设计者的劳动强度。现代EDA技术代表了当今电子设计技术的最新发展方向,它的基本特征是采用了硬件描述语言进行电路与系统的设计,具有系统仿真和综合能力。超大规模可编程逻辑器件是EDA得以实现的硬件基础,具有硬件测试和实现快捷、开发效率高、技术维护简单、工作可靠性好等特点。

现场可编程门阵列(Field Programmable Gate Arrays,FPGA)是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。它是一种可编程使用的信号处理器件。通过改变配置信息,用户可对其功能进行定义,以满足设计需求。通过开发,FPGA能够实现任何数字器件的功能。与传统数字电路相比,FPGA具有可编程、高集成度、高可靠度和高速等优点。

FPGA采用了逻辑单元阵列LCA(Logic Cell Array)这样一个概念,内部包括可配置逻辑模块CLB(Configurable Logic Block)、输入输出模块IOB(Input Output

5

Block)和内部连线(Interconnect)三个部分。 现场可编程门阵列(FPGA)是可编程器件,与传统逻辑电路和门阵列(如PAL,GAL及CPLD器件)相比,FPGA具有不同的结构。FPGA利用小型查找表(16×1RAM)来实现组合逻辑,每个查找表连接到一个D触发器的输入端,触发器再来驱动其他逻辑电路或驱动I/O,由此构成了既可实现组合逻辑功能又可实现时序逻辑功能的基本逻辑单元模块,这些模块间利用金属连线互相连接或连接到I/O模块。FPGA的逻辑是通过向内部静态存储单元加载编程数据来实现的,存储在存储器单元中的值决定了逻辑单元的逻辑功能以及各模块之间或模块与I/O间的联接方式,并最终决定了FPGA所能实现的功能,FPGA允许无限次的编程。

硬件描述语言HDL(Hardware Description Language)是一种电子系统硬件行为描述、结构描述、数据流描述的语言。利用这种语言,数字电路系统的设计可以从顶层到底层(从抽象到具体)逐层描述自己的设计思想,用一系列分层次的模块来表示极其复杂的数字系统。然后,利用电子设计自动化( EDA )工具,逐层进行仿真验证,再把其中需要变为实际电路的模块组合,经过自动综合工具转换到门级电路网表。接下去,再用专用集成电路 ASIC 或现场可编程门阵列 FPGA 自动布局布线工具,把网表转换为要实现的具体电路布线结构。目前,电子系统向集成化、大规模和高速度等方向发展,以硬件描述语言和逻辑综合为基础的自顶向下的电路设计方法在业界得到迅猛发展,HDL 在这种形势下显示出了巨大的优势,展望将来HDL 在硬件设计领域的地位将与C 和C++在软件设计领域的地位一样,在大规模数字系统的设计中,它将逐步取代传统的逻辑状态表和逻辑电路图等硬件描述方法,而成为主要的硬件描述工具。

Verilog HDL是工业和学术界的硬件设计者使用的两种主流的HDL 之一,另一种是VHDL,这两种HDL都已成为IEEE 标准。两者各有特点,但Verilog HDL 拥有更悠久的历史、更广泛的设计群体,资源也远比VHDL 丰富,且非常容易学习掌握。Verilog HDL是在用途最广泛的C语言的基础上发展起来的一种硬件描述语言,最大特点就是易学易用,如果有C语言的编程经验,可以在一个较短的时间内很快的学习和掌握,但它较自由的语法,也容易使初学者犯一些错误。Verilog HDL用于从算法级、门级到开关级的多种抽象设计层次的数字系统建模,被建模的数字系统对象的复杂性可以介于简单的门和完整的电子数字系统之间。数字系

6

统能够按层次描述,并可在相同描述中显式地进行时序建模。Verilog HDL 语言具有下述描述能力:设计的行为特性、设计的数据流特性、设计的结构。组成以及包含响应监控和设计验证方面的时延和波形产生机制都使用同一种建模语言。此外,Verilog HDL语言提供了编程语言接口,通过该接口可以在模拟、验证期间从设计外部访问设计,包括模拟的具体控制和运行。Verilog HDL语言不仅定义了语法,而且对每个语法结构都定义了清晰的模拟、仿真语义。因此,用这种语言编写的模型能够使用Verilog仿真器进行验证。Verilog HDL提供了扩展的建模能力,这对大多数建模应用来说已经足够。当然,完整的硬件描述语言足以对从最复杂的芯片到完整的电子系统进行描述。

1.2 项目创意

数字钟是采用数字电路实现对时、分、秒数字显示的计时装置,是人们日常生活中不可少的必需品。它是近代世界钟表业界的第三次:第一次是摆和摆轮游丝的发明,相对稳定的机械振荡频率源使钟表的走时差从分级缩小到秒级,代表性的产品就是带有摆或摆轮游丝的机械钟或表。第二次是石英晶体振荡器的应用,发明了走时精度更高的石英电子钟表,使钟表的走时月差从分级缩小到秒级。第三次就是单片机数码计时技术的应用,使计时产品的走时日差从分级缩小到1/600万秒,从原有传统指针计时的方式发展为人们更为熟悉的数字显示方式。钟表的数字化给人们生产生活带来了很大的方便,而且极大的扩展了钟表原先的功能。因此,电子时钟的出现给钟表计时业界带来了跨跃性的进步。

数字钟的设计方法有许多种,例如可用中小规模集成电路组成电子钟,也可以利用专用的电子钟芯片配以显示电路及其所需要的外围电路组成电子钟,还可以利用单片机来实现电子钟等等。这些方法都各有其特点,本次课程设计我们基于FPGA设计并开发一个数字钟,并且附带多种功能。

7

2 需求分析

2.1 任务目标

设计开发一个基于FPGA器件的多功能数字钟,数字钟实现的功能如下: 基本功能:

1.计时、校时与校分(自动校时、手动校时、指定时间(时、分、秒)校时);

2.报整点、广播报时;

3.闹钟与闹钟设置.:对闹钟时间的设定并在当前显示时间到时后能够进行闹钟提示。 拓展功能:

1. 日期:具备显示日期、设定日期、自动调整日期功能; 2. 秒表:具备显示功能、开始与暂停功能、清零功能; 3. 电子琴:具备21个声调的发音以及显示功能; 4. 延时闹钟:具备使闹钟时间延迟的功能; 5. 音乐闹钟:具备多种音乐供使用者选择为闹钟。

2.2 元件清单

元件名称 FPGA开发板DE0(Altera) 数据线 电源线 蜂鸣器 电路板 三极管 电阻 导线

8

数量 1块 1根 1根 1个 1块 1个 若干 若干 2.3小组分工

小组成员 王艺敏 张翼飞 朱天宇

其中我负责计时、报时、秒表、日期、电子琴等功能的设计和实现: 1.计时、校时与校分(自动校时、手动校时、指定时间(时、分、秒)校时);

2. 日期:具备显示日期、设定日期、自动调整日期功能; 3. 秒表:具备显示功能、开始与暂停功能、清零功能; 4. 电子琴:具备21个声调的发音以及显示功能。

负责功能 闹钟、音乐闹钟、延时闹钟 计时、报时、秒表、日期、电子琴 显示、蜂鸣器电路 3系统设计

3.1 系统主板电路分析

DE0 开发板上的硬件:Altera Cyclone® III 3C16 FPGA 器件;Altera 系列配置– EPCS4;板上USB Blaster 用于编程 ,支持JTAG 模式和 AS 模式;8 MB SDRAM ;4 MB 闪存 ;SD 卡槽; 3个按钮开关;10个拨动开关; 10个绿色LED ;50-MHz 振荡器时钟源 ;VGA DAC (4-bit 电阻网络) 带有VGA 输出接口; RS-232 接收器; PS/2 鼠标/键盘接口;两个40-pin 扩展口。

下图为DE0开发板系统框图。为了提供用户最大灵活性,所有连接均通过Cyclone IIII FPGA 器件完成,因此用户可以配置FPGA来完成任何系统设计。

9

Cyclone IIII 3C16 FPGA •15,408 逻辑单元 •56 M9K 内存模块 •504K RAM •56个内嵌乘法器 •4 个锁相环 •346 个I/O pins

•细间距球栅阵列484pins封装 内置USB Blaster 电路

•板上USB Blaster,用于编程及用户API (Application programming interface) 控制

•使用Altera EPM240 CPLD SDRAM

•单颗8MB SDR SDRAM芯片 •支持16-bits数据总线 闪存

10

• 4MB NOR 闪存

•支持Byte (8-bits)/Word (16-bits) 模式 SD 插口

•提供SPI 模式和1位SD 模式用于SD 卡接入 按钮开关 •3 个按钮开关

•常闭开关,按下时产生低电平脉冲 滑动开关 •10 个滑动开关

• 相应产生逻辑0与逻辑1 人机界面 •10 个绿色LED •4 个七段显示器

•16x2 LCD 接口(不含LCD模块) 时钟输入 •50-MHz 振荡器 VGA 输出

•4-bit 电阻式DAC(数位类比转换) •15-pin高密度D型接头 •最高支持1280x1024 每秒60幅 序列ports

•一组RS-232 port (不含DB-9 连接器)

•一组PS/2 port (若要同时接滑鼠与键盘可使用PS/2 Y Cable 来扩充) 两个 40-pin 扩充槽

•72 个I/O 接脚以及8个电源与接地接脚

•用于40-pin 扩充槽的排线可利用IDE硬碟专用的40-pin 排线

1. LED灯和开关

DE0开发板提供了3个按钮开关,分别为BUTTON0, BUTTON1和 BUTTON2,

11

均直接连接至 Cyclone III FPGA芯片。 每个按钮开关没有被按下时,会输出高电平(3.3 V);被按下则会输出低电平(0 V)。

DE0开发板上同时也提供了10 个拨动开关。这些拨动开关均没有去抖动电路,故一般供电平敏感的电路做信号输入之用。每个拨动开关均直接连接至Cyclone III FPGA芯片上的一个特定引脚。当拨动开关置于DOWN档 (接近板子的边缘)时,它会提供一个低电平 (0 V) 的输入至PGA,当其置于 UP 档时,将会提供一个高电平(3.3 V)的输入。

DE0开发板上还提供了10个可供用户控制的 LED灯。每一个LED灯均是由Cyclone III FPGA芯片上的特定引脚直接驱动的;将其相对应的引脚置于高电平可点亮LED 灯,置于低电平则将熄灭LED灯。下图分别给出了按钮开关,拨动开关与Cyclone III FPGA芯片的连接示意图。

12

2.七段数码管

DE0 开发板上提供了4个七段数码管。分为2组,每组2个,用于显示不同大小的数字。如图所示,七段数码管已连接至 Cyclone III FPGA芯片的相应引脚。FPGA输出低电压的时候,对应的字码段点亮,反之则熄灭。 数码管的每一个字段都被从0到 6依次编号,如图所示。除此之外,小数点被定义为DP。下表给出了所有七段数码管与FPGA芯片的引脚连接信息。

13

信号名 FPGA引脚号 说明

HEX0_D[0] PIN_E11 Seven Segment Digit 0[0] HEX0_D[1] PIN_F11 Seven Segment Digit 0[1] HEX0_D[2] PIN_H12 Seven Segment Digit 0[2] HEX0_D[3] PIN_H13 Seven Segment Digit 0[3] HEX0_D[4] PIN_G12 Seven Segment Digit 0[4] HEX0_D[5] PIN_F12 Seven Segment Digit 0[5] HEX0_D[6] PIN_F13 Seven Segment Digit 0[6] HEX0_DP PIN_D13 Seven Segment Decimal Point 0 HEX1_D[0] PIN_A13 Seven Segment Digit 1[0] HEX1_D[1] PIN_B13 Seven Segment Digit 1[1] HEX1_D[2] PIN_C13 Seven Segment Digit 1[2] HEX1_D[3] PIN_A14 Seven Segment Digit 1[3] HEX1_D[4] PIN_B14 Seven Segment Digit 1[4] HEX1_D[5] PIN_E14 Seven Segment Digit 1[5] HEX1_D[6] PIN_A15 Seven Segment Digit 1[6] HEX1_DP PIN_B15 Seven Segment Decimal Point 1 HEX2_D[0] PIN_D15 Seven Segment Digit 2[0] HEX2_D[1] PIN_A16 Seven Segment Digit 2[1] HEX2_D[2] PIN_B16 Seven Segment Digit 2[2] HEX2_D[3] PIN_E15 Seven Segment Digit 2[3] HEX2_D[4] PIN_A17 Seven Segment Digit 2[4]

14

HEX2_D[5] PIN_B17 Seven Segment Digit 2[5] HEX2_D[6] PIN_F14 Seven Segment Digit 2[6] HEX2_DP PIN_A18 Seven Segment Decimal Point 2 HEX3_D[0] PIN_B18 Seven Segment Digit 3[0] HEX3_D[1] PIN_F15 Seven Segment Digit 3[1] HEX3_D[2] PIN_A19 Seven Segment Digit 3[2] HEX3_D[3] PIN_B19 Seven Segment Digit 3[3] HEX3_D[4] PIN_C19 Seven Segment Digit 3[4] HEX3_D[5] PIN_D19 Seven Segment Digit 3[5] HEX3_D[6] PIN_G15 Seven Segment Digit 3[6] HEX3_DP PIN_G16 Seven Segment Decimal Point 3 3. 时钟电路

DE0 开发板提供了一个 50 MHz 的时钟信号。 该已连接至 FPGA 芯片的时钟信号可用于驱动FPGA 内的用户逻辑电路。 除此之外,所有的时钟输入都连接至 FPGA 芯片的 PLL 时钟输入引脚,从而允许用户将这些时钟信号作为 PLL 电路的信号输入源。

DE0 开发板上的时钟分配信息如图:

4. 扩展接头

DE0 开发板上有提供两个 40-pin 扩展接头。每个接头都直接连接至 Cyclone III FPGA 芯片上的36个引脚,同时也提供了 DC +5V (VCC5), DC +3.3V

15

(VCC33)引脚和2个GND 引脚。在这36个 I/O 引脚中,4个引脚连接至 FPGA 芯片的 PLL 时钟输入与输出引脚,允许扩展子卡访问 FPGA 芯片的 PLL 模块。

最后, 图 4-13 给出了相关的示意图。该图显示了这两个接头上的保护电路,但是该电路包含了所有的 72 数据引脚。

3.2模块化设计方案

根据需求,将整个系统划分为以下几个模块:

1. 分频模块:由于FPGA内部提供的时钟信号频率大约为50MHz,所以需要将它转化成1Hz的标准时钟信号供数字钟的计时显示。 2. 计时模块:进行计时和调时的功能模块。 3. 闹钟模块:用于调整和控制闹钟。

4. 控制模块:总体控制各个功能的启动和切换。 5. 显示模块:实现对各个功能的显示。 6. 秒表模块:实现秒表功能。 7. 音乐模块:实现音乐数字钟功能。 8. 日期模块:实现日期的控制和调整功能。 9. 电子琴模块:实现电子琴的各种功能。

16

总体模块设计框图:

其中我负责的模块有: 1.

分频模块:由于FPGA内部提供的时钟信号频率大约为50MHz,所以需

要将它转化成1Hz的标准时钟信号供数字钟的计时显示。 2. 3. 4. 5. 6.

计时模块:进行计时和调时的功能模块。 控制模块:总体控制各个功能的启动和切换。 秒表模块:实现秒表功能。

日期模块:实现日期的控制和调整功能。 电子琴模块:实现电子琴的各种功能。

4 模块电路设计

4.1顶层模块

顶层模块框图:

17

顶层模块的输入输出信号定义:

module clock(clk,switch,key,seg_out0,seg_out1,seg_out2,seg_out3,beep);// 模块名 input clk; // 输入时钟 input [7:0] switch; //输入开关: switch[0]显示切换,switch[1]设置

//switch[2]闹钟,switch[3]闹钟开关,switch[4]秒表//switch[5]秒表开关,switch[6]日期,switch[7]电子琴

input [2:0] key; //输入按键 ,key[2:0]分别为秒,分钟,小时的增加按键。 output reg[7:0] seg_out0,seg_out1,seg_out2,seg_out3; // 数码管0123的输 //出引脚 output beep; //蜂鸣器输出端

对各个接口信号及寄存器定义:

reg [14:0] count; //定义计数寄存器 reg [5:0] count1; //定义计数寄存器1 reg [4:0] count2; //定义计数寄存器2 reg [2:0] count3; //定义计数寄存器3 reg [23:0] count4; //定义计数寄存器4 reg [7:0] countpu; reg clk_ms; //1ms时钟 reg clk_10ms; //10ms时钟 reg clk_100ms; //100ms时钟 reg clk_day=0; //1day时钟 reg clk_4hz; //4hz时钟 reg [23:0] now_time = 24'h080057; // 定义现在时刻寄存器 reg [23:0] clk_time = 24'h080100; //定义闹钟时刻寄存器 reg [23:0] stp_time = 24'h000000; //定义秒表时刻寄存器 reg [31:0] now_dat = 32'h20170604; //定义日期寄存器 reg [7:0] day_number; //定义日数寄存器 reg [15:0] show_data; //定义数据寄存器 reg [16:0] jishu_count = 17'd0; reg [16:0] alarm_count = 17'd131071; reg [16:0] plmusic_count = 17'd131071; reg [7:0] music_key; //定义音调寄存器,[7:4]为123分别表示低中高音,[3:0]为1234567分别为音调。

18

reg [7:0] r_switch; //定义按键寄存器

reg [2:0] dout1 = 3'b111; //按键寄存器 reg [2:0] dout2 = 3'b111; reg [2:0] dout3 = 3'b111;

wire [2:0] time_set; //秒分时设置输出 wire show_sec; //0显示时分,1显示秒 wire show_clk; //0显示时间,1显示闹钟

reg [3:0] alarm_set = 4'h1; reg alarm; reg beep_s=1; reg baoshi;

4.2分频模块

4.2.1 分频模块设计

对于分频模块,目的是使用原有的50Mhz的时钟信号生成需要的1ms、10ms、100ms、4hz的时钟信号,分别用于计时模块、控制模块、秒表模块、日期模块、闹钟模块、音乐模块、电子琴模块。框图如下图:

clk 分频模块 clk_ms clk_10ms clk_100ms clk_4hz 关键代码及注释:

//1ms信号产生部分

always @(posedge clk) // 定义 clock 上升沿触发 begin

count = count + 1'b1;

if(count == 15'd25000) //0.5mS到了吗? begin

count = 15'd0; //计数器清零 clk_ms = ~clk_ms; //置位ms标志

19

end

end

//10ms信号产生部分 always @(posedge clk_ms) begin end

//100ms信号产生部分

always @(posedge clk_ms) // 定义 clock 上升沿触发 begin end

//4hz信号产生部分 always@(posedge clk) begin

count4 = count4 + 1'b1;

if(count4 == 24'd6250000) //25ms到了吗 begin end

20

count3 = count3 + 1'b1; if(count3 == 3'd5) begin end

count3 = 3'd0; clk_10ms = ~clk_10ms;

count1 = count1 + 1'b1;

if(count1 == 6'd50) //50mS到了吗? begin

count1 = 6'd0; //计数器清零

clk_100ms = ~clk_100ms; //置位100毫秒标志

end

//定义 clock 上升沿触发

count4 = 24'd0; clk_4hz = ~clk_4hz;

end

4.2.2 分频模块仿真

通过设置功能仿真,检查代码的正确性:

由仿真可知模块正确。

4.3 计时模块

4.3.1 计时模块设计

计时模块是采用16进制来实现的,将now_time[23:0]定义为其时分秒,其中now_time[3:0]为其秒钟上的个位数值,now_time[7:4]为其秒钟上的十位数值,now_time[11:8]为其分钟上的个位数值,now_time[15:12]为其分钟上的十位数值,now_time[19:16]为其时钟上的个位数值,now_time[23:20]为其时钟上的十位数值。当自动计时时,秒脉冲过来,秒个位now_time [3:0]便开始加1,当加到9时,秒十位加1,与此同时秒个位清零,继续加1。当秒十位now_time[7:4]为5秒个位为9时(即59秒),分个位now_time [11:8]加1,与此同时秒个位和秒十位都清零。以此类推,当分十位now_time [15:12]为5和分个位为9时(即59分),时个位加1,与此同时时个位now_time [19:16]和分十位都清零。当时十位now_time [23:20]为2和时个位为4,全部清零,开始重新计时。而当调时时,根据按键不同,分别使秒个位、分个位、时个位加1,但秒分时之间没有进位。从功能上讲分别为模60计数器,模60计数器和模24计数器。

关键代码及注释:

//计时和调时模块 //调整时间 begin

21

if(time_set[2]) //调秒 begin now_time[3:0] = now_time[3:0] + 1'b1; //秒加 1 if(now_time[3:0] >= 4'ha) //加到10,复位 begin now_time[3:0] = 4'h0; now_time[7:4] = now_time[7:4] + 1'b1; // 秒的十位加一 if(now_time[7:4] >= 4'h6) //加到6,复位 now_time[7:4] = 4'h0; end end else if(time_set[1]) //调分 begin

now_time[11:8] = now_time[11:8] + 1'b1; //分个位加一 if(now_time[11:8] >= 4'ha) //加到10,复位 begin now_time[11:8] = 4'h0; now_time[15:12] = now_time[15:12] + 1'b1; //分十位加一 if(now_time[15:12] >= 4'h6) //加到6,复位 now_time[15:12] = 4'h0; end

//调时

end

else if(time_set[0]) begin

now_time[19:16] = now_time[19:16] + 1'b1; //时个位加一 if(now_time[19:16] >= 4'ha) //加到10,复位 begin now_time[19:16] = 4'h0; now_time[23:20] = now_time[23:20] + 1'b1; //时十位加一 end

if(now_time[23:16] >= 8'h24) //加到24,复位 now_time[23:16] = 8'h0; end end // 计 时 begin count2 = count2 + 1'b1; if(count2==4'd10) begin count2=4'd0; now_time[3:0] = now_time[3:0] + 1'b1; //秒加 1 if(now_time[3:0] >= 4'ha) begin now_time[3:0] = 4'h0;

22

now_time[7:4] = now_time[7:4] + 1'b1; // 秒的十位加一 if(now_time[7:4] >= 4'h6) begin now_time[7:4] = 4'h0;

now_time[11:8] = now_time[11:8] + 1'b1; //分个位加一 if(now_time[11:8] >= 4'ha) begin now_time[11:8] = 4'h0;

now_time[15:12]=now_time[15:12] + 1'b1;//分十位加一 if(now_time[15:12] >= 4'h6) begin

now_time[15:12] = 4'h0;

now_time[19:16]=now_time[19:16]+1'b1;//时个位加一 if(now_time[19:16] >= 4'ha) begin

now_time[19:16] = 4'h0;

now_time[23:20]=now_time[23:20] + 1'b1; //时十位加一 if(now_time[23:16] >= 8'h24) begin now_time[23:16] = 8'h0; clk_day=~clk_day; end end end end end end end

4.3.2 计时模块仿真

通过设置功能仿真,检查代码的正确性:

由仿真可知模块正确。

23

4.4 控制模块

4.4.1 控制模块设计

对按键实现去抖处理,对开关进行重新定义,并且对按键开关进行译码确保其他模块的功能实现。

部分关键代码及注释:

assign time_set = ~(key|dout3); // 按键消抖输出 always @(posedge count1[5]) //按键去噪声 begin dout1 <= key; dout2 <= dout1; dout3 <= dout2; //连续赋值 end

4.4.2 控制模块仿真

通过设置功能仿真,检查代码的正确性:

由仿真可知模块正确。

4.5 秒表模块

4.5.1 秒表模块设计

秒表模块是采用16进制来实现的,将stp_time[23:0]定义为其分、秒、

10ms,其中stp_time[3:0]为其10ms位上的个位数值,stp_time[7:4]为其10ms位上的十位数值,stp_time[11:8]为其秒钟上的个位数值,stp_time[15:12]为其秒钟上的十位数值,stp_time[19:16]为其分钟上的个位数值,stp_time[23:20]为其分钟上的十位数值。当开始计时时,10ms脉冲过来,10ms个位stp_time [3:0]便开始加1,当加到9时,10ms十位加1,与此同时10ms个位清零,继续加1。当10ms

24

十位stp_time[7:4]为9、10ms个位为9时(即0.99秒),秒个位stp_time [11:8]加1,与此同时10毫秒个位和10毫秒十位都清零。以此类推,当秒十位stp_time [15:12]为5和秒个位为9时(即59秒),分个位加1,与此同时时秒个位stp_time [19:16]和秒十位都清零。当分十位stp_time [23:20]为5和分个位为9时,达到秒表计时的上限,将stp_time[23:0]恒为24’h595999。而当重置时,将stp_time[23:0]清零。从功能上讲分别为模60计数器,模60计数器和模100计数器。 关键代码及注释:

//秒表模块

always @(negedge clk_10ms) begin if(switch[4]==1&&time_set>=1&&(!switch[7]))

stp_time=24'h000000; //重置秒表 else if(switch[5]==0) ; else begin

stp_time[3:0] = stp_time[3:0] + 1'b1; //10ms加 1 if(stp_time[3:0] >= 4'ha) begin stp_time[3:0] = 4'h0;

stp_time[7:4] = stp_time[7:4] + 1'b1; // 10ms的十位加一 if(stp_time[7:4] >= 4'ha) begin stp_time[7:4] = 4'h0;

stp_time[11:8] = stp_time[11:8] + 1'b1; //秒个位加一 if(stp_time[11:8] >= 4'ha) begin stp_time[11:8] = 4'h0; stp_time[15:12] = stp_time[15:12] + 1'b1; //秒十位加一 if(stp_time[15:12] >= 4'h6) begin stp_time[15:12] = 4'h0;

stp_time[19:16] = stp_time[19:16] + 1'b1; //分个位加一 if(stp_time[19:16] >= 4'ha) begin

stp_time[19:16] = 4'h0;

stp_time[23:20]=stp_time[23:20]+1'b1;//分十位加一 if(stp_time[23:16] >= 8'h60) stp_time = 24'h595999; end end

25

end

end end end end

4.6 日期模块

4.6.1 日期模块设计

由于一年中各个月份的日的长短不同,共有二十八、二十九、三十和三十一天四种情况,可知日由年和月共同决定。二十九天的几率很低,为了方便起见,忽视闰年的情况,将所有年的二月视为二十八天。其中,一月、三月、五月、七月、八月、十月和十二月有三十一天,四月、六月、九月、十一月有三十天;二月有二十八天。

日期模块是采用16进制来实现的,将now_dat [31:0]定义为其年月日,其中

now_dat[3:0]为其日位的个位数值,now_dat[7:4]为其日位上的十位数值,now_ dat[11:8]为其月位上的个位数值,now_ dat[15:12]为其月位上的十位数值,now_ dat[19:16]为其年位上的个位数值,now_ dat[23:20]为其年位上的十位数值,now_ dat[27:24]为其年位上的百位数值,now_ dat[31:28]为其年位上的千位数值。当自动计日期时,日脉冲过来,日个位now_ dat [3:0]便开始加1,当加到9时,日十位加1,与此同时日个位清零,继续加1。根据当前月份,确定当月的日数day_number,当日位now_dat[7:0]大于这个day_number时,月个位now_ dat[11:8]加1,与此同时日个位置一,日十位清零。以此类推,当月十位now_ dat[15:12]为1和月个位大于2时(即12),年个位加1,与此同时月个位now_dat[11:8]置一,月十位清零。依次进位,当年位now_ dat[31:16]大于16’h9999时,全部清零,开始重新计年。而当调日期时,根据按键不同,分别使日个位、月个位、年个位、年十位、年百位加1,但日、月、年个位、年十位、年百位之间没有进位。从功能上讲分别为模30(或29或27)计数器,模11计数器、模10计数器、模10计数器、模100计数器。

部分关键代码及注释:

//日期模块

26

//调整日期

//调日 begin

end //调月 begin

now_dat[3:0] = now_dat[3:0] + 1'b1; //日加 1

if(now_dat[3:0] >= 4'ha) //加到10,复位 begin now_dat[3:0] = 4'h0; now_dat[7:4] = now_dat[7:4] + 1'b1; // 日的十位加一 end

case(now_dat[15:8]) //根据月份为天数赋值 8'h01, 8'h03, 8'h05, 8'h07, 8'h08, 8'h10, 8'h12: day_number=8'h31; 8'h02: day_number=8'h28; 8'h04, 8'h06, 8'h09, 8'h11: day_number=8'h30; endcase

if(now_dat[7:0] > day_number) //加到对应的天数,复位为1 now_dat[7:0] = 8'h01;

now_dat[11:8] = now_dat[11:8] + 1'b1; //月个位加一 if(now_dat[11:8] >= 4'ha) //加到10,复位 begin now_dat[11:8] = 4'h0;

now_dat[15:12] = now_dat[15:12] + 1'b1; //月十位加一

end if(now_dat[15:8] > 8'h12) //加到12,复位为1 now_dat[15:8] = 8'h01; end

//调年个位 begin now_dat[19:16] = now_dat[19:16] + 1'b1; //年个位加一 if(now_dat[19:16] >= 4'ha) //加到10,复位 now_dat[19:16] = 4'h0; end

else if(!show_sec&&time_set[1]) //调年十位

27

begin

now_dat[23:20] = now_dat[23:20] + 1'b1; //年十位加一

if(now_dat[23:20] >= 4'ha) //加到10,复位 now_dat[23:20] = 4'h0; end

//调年百位 begin

now_dat[27:24]=now_dat[27:24] + 1'b1; //年百位加一 if(now_dat[27:24] >= 4'ha) begin now_dat[27:24]=0; now_dat[31:28]=now_dat[31:28] + 1'b1; if(now_dat[31:28] >= 4'ha) now_dat[31:28] = 4'h0; end end

4.7 电子琴模块

4.7.1 电子琴模块设计

不同频率的信号通过蜂鸣器的音调不同,根据该原理设计高中低七调共二十

一音电子琴。按住三个按键分别代表高中低音,拨动七个开关会产生1/2/3/4/5/6/7。用music_key[7:0]表示音调,[7:4]为123分别表示低中高音,[3:0]为1234567分别为音调。根据资料,可以得到高中低音七调共二十一音的频率,再将频率转换为对应clk的倍数存到电子琴计数器plmusic_count中,得到:低音1为958;低音2为85136;低音3为75838;低音4为71582;低音5为63776;低音6为56818;低音7为50618;中音1为47774;中音2为42568;中音3为37919;中音4为35791;中音5为31888;中音6为28409;中音7为25309;高音1为23912;高音2为21282;高音3为116;高音4为177;高音5为15944;高音6为14205;高音7为12655。 每次声音响0.25s,设置开关状态寄存器来保存前一刻的开关状态与当前开关状态比较以得到开关是否被拨动。 关键代码及注释:

//电子琴模块

begin

28

if(!(r_switch==switch)) //如果前一刻开关状态与当前开关不同 begin casex(r_switch^switch) //为音调赋值 8'bx1xxxxxx: music_key[3:0]=4'h1; 8'bxx1xxxxx: music_key[3:0]=4'h2; 8'bxxx1xxxx: music_key[3:0]=4'h3; 8'bxxxx1xxx: music_key[3:0]=4'h4; 8'bxxxxx1xx: music_key[3:0]=4'h5; 8'bxxxxxx1x: music_key[3:0]=4'h6; 8'bxxxxxxx1: music_key[3:0]=4'h7; default: music_key[3:0]=4'h0; endcase

casex(time_set) //为音调的低中高音赋值 3'bx1x: music_key[7:4]=4'h2; 3'b1xx: music_key[7:4]=4'h1; 3'bxx1: music_key[7:4]=4'h3; default: music_key[7:4]=4'h2; endcase end else music_key=8'haa; case(music_key) //根据音调配置频率 8'h10: plmusic_count=17'd131071; 8'h11: plmusic_count=17'd958; 8'h12: plmusic_count=17'd85136; 8'h13: plmusic_count=17'd75838; 8'h14: plmusic_count=17'd71582; 8'h15: plmusic_count=17'd63776; 8'h16: plmusic_count=17'd56818; 8'h17: plmusic_count=17'd50618; 8'h20: plmusic_count=17'd131071; 8'h21: plmusic_count=17'd47774; 8'h22: plmusic_count=17'd42568; 8'h23: plmusic_count=17'd37919; 8'h24: plmusic_count=17'd35791; 8'h25: plmusic_count=17'd31888; 8'h26: plmusic_count=17'd28409; 8'h27: plmusic_count=17'd25309; 8'h30: plmusic_count=17'd131071; 8'h31: plmusic_count=17'd23912; 8'h32: plmusic_count=17'd21282; 8'h33: plmusic_count=17'd116; 8'h34: plmusic_count=17'd177;

29

8'h35: plmusic_count=17'd15944; 8'h36: plmusic_count=17'd14205; 8'h37: plmusic_count=17'd12655; default:plmusic_count=17'd131071; endcase end else plmusic_count=17'd131071; //重置频率

r_switch = switch;

//记录switch的状态到寄存器中

5 系统调试及结果分析

5.1 硬件检查

在软件联机调试之前,首先要确定硬件是否能完全正常工作。

检查方面主要包括:(1)PC机的接口和核心板上的JTAG下载口是否连接正确; (2)蜂鸣器的电路是否为通路; (3)检查接地、电源线是否连接正确; (4)用示波器检测核心板的各个引脚是否有信号输出; (5)LED七段数码管显示正常。

经测试,各硬件一切正常。

5.2 软件编译

在检查代码没有问题后,对软件进行编译后得到的结果:

30

共有173个warning,略多但可以接受。

程序使用了994个逻辑单元,使用率为6%,占用资源较少。

5.3 调试过程及结果

将程序下载到板子中运行:各模块调试顺序为计时模块-日期模块-秒表模块-

电子琴模块。

1.计时模块:进行计时模块的调试。

时间模块需要实现时、分、秒的正确走时,时分显示和秒显示的切换,时、分、秒的正确调时。

调试结果为时、分、秒走时正确,时分显示和秒显示切换正常,时、分、秒的调时正确。

2.日期模块:进行日期模块的调试。

日期模块需要实现年、月、日的正确计日,年显示和月日显示的切换,年、月、日的正确调整。

调试结果为年、月、日能够正确计日,年显示和月日显示切换正常,年、月、日的调整正确。

31

3.秒表模块:进行秒表模块的调试。

秒表模块需要实现秒表的正确计数,两种显示模式的切换,暂停/跑表的正确运行,清零的正确实现。

调试的结果为秒表能正确计数,并且能在两种显示模式间智能和手动切换,能够暂停和继续,能够清零,能够后台跑表。

4.电子琴模块:进行电子琴模块的调试。

电子琴模块需要实现二十一种音调的正确发音,按键开关的正确发音,以及音调的正确显示,以及电子琴模式下的按键开关对其他模式无影响。

调试的结果为能够通过按键开关实现二十一种音调的正确发音,以及音调的正确显示,并且在电子琴模式下按键开关对其他模式无影响。

5.其他的显示模块、控制模块、分频模块通过以上四个模块的调试,显然能够验证到该三个模块的正确性。

5.4 调试注意事项

软件设计时,需要确定好软件设计的思路,即先确定各个功能需要实现的先后,再将各功能模块单独进行编写调试,待各模块功能完善后,再进行总体联合调试。调试过程中出现的一些问题,要一一解决。需要注意的有:

(1)在进行系统联机调试时,要注意电源是否接通,PC机的接口和核心板上的JTAG下载口是否连接正确。确定将未使用的引脚设置为三态输入,否则可能会损坏芯片。

(2)进行调试之前,要检查硬件,蜂鸣器的电路是否为通路;接地、电源线是否连接正确;用示波器检测核心板的各个引脚是否有信号输出;LED七段数码管显示是否正常。

(3)调试中,要按照合理的顺序进行调试,如果出现了问题,要仔细研究问题产生的原因,并耐心解决。

32

6 总结

6.1课设中出现的问题与解决方案

(1)计时模块崩溃,出现数字乱跑现象。经过分析发现是编程中always语

句的错误应用,通过将计时和调时写入同一个always语句中解决了问题。

(2)计时偏快现象。经检查发现是对系统原时钟clk的频率出现了错误,将

clk频率改为了50Mhz。

(3)电子琴不发声现象。经过分析发现是always的时钟频率太低,不能计

时响应按键开关,将时钟改为4hz解决了问题。

(4)电子琴间歇性失灵现象。经过仿真发现程序并没有错误,最后发现是蜂鸣器电路接触不良导致的,通过重新焊接蜂鸣器电路解决了问题。

(5)显示模块十分繁琐,通过对模块接口的简化以及case语句改进了显示模块的机构,使之大大简化和优化。

(6)使用的开关太多,通过对不同情况下开关和按键的组合复用,将使用的开关减少到七个,减少了输出端口的数量

6.2心得体会

为期四周的大型课程设计,我们组顺利完成了基于FPGA的数字电子时钟设计与实现的课程设计。从刚开始对Verilog语言的生疏,到最后能够熟练地掌握Verilog语言的程度,期间花费不少时间和精力,同时也收获了很多,学会了使用Verilog语言编程仿真电路实验,掌握了可编程逻辑器件的应用开发技术,熟悉了一种EDA软件使用,掌握了Verilog设计方法,即分模块分层次的设计方法。

在设计的过程中,因为刚刚接触这种编程语言,我们也遇到了很多问题。但是我们没有放弃过,不断检查纠正错误。Verilog源程序的编写很容易出现错误,这就需要耐心的调试。因为很多情况下,一长串的错误往往是由一个不经意的小错误引起的。有时程序一直出错找不到原因的时候,我们也会去虚心向别的组的同学请教,或者和他们一起讨论问题,从中得到一些启发。而在Verilog HDL语言的学习上还存在一些问题,没有深入的学习,经常出现一些低级的实物,对于

33

有些语法错误,还需要仔细的查找。

数字钟在生活中无处不在,设计的过程要考虑到人们的使用习惯,设计出更人性化的产品,这样才会是一个好的设计。通过数字时钟的设计,我们可以知道,对数字时钟来说,其实只会占用很少逻辑资源,这也意味着如果制作成SOC的话,成本会非常的低,所以基于这点,整个模块也可以依附在其他功能产品上。我们设计的这个数字钟还有很多的不足,比如系统模块化不够细致,某些功能设计不够新颖,操作上比较复杂等等。

这次课程设计让我受益匪浅,不仅让我又掌握了一些知识,更是提高了我们的动手能力和科学严谨的精神。同时也培养了我们自学的能力,遇到不明白的地方可以通过思考、查资料、与同学交流多种方式解决问题。这些对于我以后的学习和工作都有极大的帮助。

最后,我要感谢汪小燕老师耐心的指导,在迷茫的时候,为我们指明了方向;

在遇到问题的时候,用悉心的指导帮助和不厌其烦的讲解为我们解惑;在完成课设之后,用严格的要求为我们找到能够精益求精的地方。同时也要感谢学院提供这一次的机会让我们学到更多知识,并且提供了这么好的学习条件,设备、学习环境、师资等方面都非常好。

34

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuoyibo.cn 版权所有 湘ICP备2023022426号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务