基于FPGA的数字电子时钟设计与实现

基于FPGA的数字电子时钟设计与实现

《数字电子技术》课程设计

设计题目:基于FPGA的数字电子时钟设计与实现

系部:电子与信息工程系

专业班级:电子信息工程08秋(1)班

小组成员:胡修远

学号: 08031145 指导教师:陶亚雄周丽婕

完成日期: 2012年 1 月

目录

一、所用设备与器材 (1)

1.1仪器设备 (1)

二.系统方案 (1)

2.1 设计思想 (1)

2.1.1课题背景 (1)

2.1.2 Quartus II软件 (3)

2.2工作原理及系统框图 (8)

三.软件方案 (9)

3.1 程序流程图 (9)

3.1.1 24进制 (9)

3.1.2 10进制流程图 (10)

3.1.3 6进制 (11)

3.1.4 60进制 (11)

3.1.5 from0to9 (12)

3.1.6 分频模块 (12)

3.1.7 总流程图 (13)

3.2 程序清单 (14)

3.2.1头文件complete_clock程序 (14)

3.2.2 counter24程序 (15)

3.2.3 counter60程序 (15)

3.2.4 from0to9程序 (16)

3.2.5 counter6程序 (17)

3.2.6 counter10程序 (17)

3.2.7 分频程序 (17)

3.2.8 校时模块程序 (18)

四.调试及结果 (18)

4.1 模块仿真 (18)

4.1.1 counter10模块仿真 (18)

4.1.2 counter24模块仿真 (19)

4.1.3 counter60模块仿真 (19)

4.1.4 分频模块仿真 (19)

4.1.5 top_clock计时模块仿真 (19)

4.2 程序下载 (20)

4.3分析运行结果 (21)

4.3.1 设计总结 (21)

4.3.2 心得体会 (21)

4.3.3 致谢 (22)

一、所用设备与器材

1.1仪器设备

使用仪器设备有FPGA DE2-70开发板、PC机、信号发生器。

基于FPGA的数字电子时钟设计与实现

图1 FPGA DE2-70开发板图

二.系统方案

2.1 设计思想

利用数字电子技术、EDA设计方法、FPGA等技术,设计、仿真并实现一个基于FPGA的数字电子时钟基本功能,其基本组成框图如图1所示,振荡器采用ALTERA的DE2-70实验板的50MHz输出,分频器将50MHz的方波进行分频进而得到1Hz的标准秒脉冲,时、分、秒计时模块分别由二十四进制时计数器、六十进制分计数器和六十进制秒计数器完成,校时模块完成时和分的校正。扩展功能设计为倒计时功能,从59分55秒至59分59秒,每秒亮一盏灯报时。

2.1.1课题背景

20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力的推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能更进一步,产品更新换代的节奏也越来越快。

20世纪80年代末,出现了FPGA(Field Progrommable Gate Array),CAE 和CAD技术的应用更为广泛,它们在PCB设计的原理图输入,自动布局布线及PCB分析,以及逻辑设计,逻辑仿真布尔综合和化简等方面担任了重要的角色,

为电子设计自动化必须解决的电路建模,标准文档及仿真测试奠定了基础。硬件描述语言是EDA技术的重要组成部分,VHDL是作为电子设计主流硬件的描述语言。本论文就是应用VHDL语言来实现秒表的电路设计。VHDL语言是标准硬件描述语言,它的特点就是能形式化抽样表示电路结构及行为,支持逻辑设计中层次领域的描述,借用了高级语言的精巧结构简化电路描述,具有电路模拟与验证及保证设计的正确性,支持电路由高层向底层的综合变换,便于文档管理,易于理解和设计重用。

EDA技术是在电子CAD技术基础上发展起来的计算机软件系统,是指以计算机为工作平台,融合了应用电子技术、计算机技术、信息处理及智能化技术的最新成果,进行电子产品的自动设计。

利用EDA工具,电子设计师可以从概念、算法、协议等开始设计电子系统,大量工作可以通过计算机完成,并可以将电子产品从电路设计、性能分析到设计出IC版图或PCB版图的整个过程在计算机上自动处理完成。

现在对EDA的概念或范畴用得很宽。包括在机械、电子、通信、航空航天、化工、矿产、生物、医学、军事等各个领域,都有EDA的应用。目前EDA 技术已在各大公司、企事业单位和科研教学部门广泛使用。例如在飞机制造过程中,从设计、性能测试及特性分析直到飞行模拟,都可能涉及到EDA技术。本文所指的EDA技术,主要针对电子电路设计、PCB设计和IC设计。EDA 设计可分为系统级、电路级和物理实现级。

用VHDL语言开发的流程:

(1)文本编辑:用任何文本编辑器都可以进行,也可以用专用的HDL编辑环境。

通常VHDL文件保存为.vhd文件。

(2)功能仿真:将文件调入HDL仿真软件进行功能仿真,检查逻辑功能是否正确(也叫前仿真,对简单的设计可以跳过这一步,只在布线完

成以后,进行时序仿真)。

(3)逻辑综合:将源文件调入逻辑综合软件进行综合,即把语言综合成最简的布尔表达式和信号的连接关系。逻辑综合软件会生成.edf

(edif)的EDA工业标准文件。

(4)布局布线:将.edf文件调入PLD厂家提供的软件中进行布线,即把设计好的逻辑安放到PLD/FPGA内。

(5)编程下载:确认仿真无误后,将文件下载到芯片中。

本设计为一个多功能的数字钟,具有时、分、秒计数显示功能,以24小时的循环计数:具有校对功能。本设计采用EDA技术,以硬件描述语言VHDL为系统逻辑描述手段设计文件,在Quartus 工具软件下,采用自顶向下的设计方式,由各个基本模块共同构建了一个基本FPGA的数字钟。

系统主芯片采用EP2C70F896C6,有时钟模块、控制模块、计时模块、数据译码模块、显示以及报时模块组成。经编译和仿真所设计的程序,在可编程逻辑器件上下载验证,本系统能够完成时、分、秒的分别显示,由按键输入进行数字钟的校时、清零、启停功能。

随着电子技术的发展,数字电路朝着速度快、容量大、体积小、重量轻的方向发展。人们对时间计量的精度要求越来越高,钟表的数字化给人们生产生活带来了极大的方便。数字钟是一种用数字电路技术实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有更更长的使用寿命,因此得到了广泛的使用。

本次设计以数字电子为主,实现对时、分、秒数字显示的计时装置,周期为24小时,显示满刻度为23时59分59秒,并具有校时功能和报时功能的数字电子钟。课程设计所采用的开发平台:Quartus II是可编程片上系统的综合性设计环境,它支持CPLD和FPGA器件的开发。FPGA (Field Programmable Gate Array)现场可编程门阵列,内部主要由许多可编程逻辑模块组成,靠纵横交错的分布式可编程互连线连接起来,可构成极其复杂的逻辑电路。本次课程设计所采用的FPGA芯片 Cyclone II系列的EP2C70F896C6。

2.1.2 Quartus II软件

Quartus II 是Altera公司的综合性PLD开发软件,支持原理图、VHDL、VerilogHDL以及AHDL(Altera Hardware Description Language)等多种设计输入形式,内嵌自有的综合器以及仿真器,可以完成从设计输入到硬件配置的完整PLD设计程。Quartus II可以在XP、Linux以及Unix上使用,除了可以使用Tcl脚本完成设计流程外,提供了完善的用户图形界面设计方式。具有运行速度快,界面统一,功能集中,易学易用等特点。

Quartus II支持Altera的IP核,包含了LPM/MegaFunction宏功能模块库,使用户可以充分利用成熟的模块,简化了设计的复杂性、加快了

设计速度。对第三方EDA工具的良好支持也使用户可以在设计流程的各个阶段使用熟悉的第三方EDA工具。

Quartus II使用基本流程如下:

1.打开Quartus II软件,创建工程

a.点击工具栏File,利用创建工程向导(New Project Wizard)创建新工程。

基于FPGA的数字电子时钟设计与实现

图2 新建工程图

b.工程目录为c:\altera\71sp1\quartus(路径中不能包含中文,不能建立在桌面上),工程名称以及顶层设计实体为counter10(以英文字母开头)。

基于FPGA的数字电子时钟设计与实现

图3 创建路径图

c.选择与开发板上芯片型号对应的器件。硬件选cycloneⅡ EP2C70F896C6。

基于FPGA的数字电子时钟设计与实现

图4 芯片选择图

d.进入第三方EDA工具选择窗口,在此可以选择使用第三方的EDA工具,如一些布局布线、综合、仿真软件。

e.确认无误后,单击Finsh完成工程创建。

f.工程创建成功后,在【Project Navigator】(资源管理窗口)显示当前工程的层次、文件和设计单元。

g.执行File—New—Design Files—verilog HDL File,建立原理图文件。

基于FPGA的数字电子时钟设计与实现

图5 原理图文件建立图

h.完成后点击File ----save as,保存到c:\altera\71sp1\quartus目录下。

i.使用文本编辑器输入源码,完成原理图编译。

j.编译工程,执行Processing—start—start Analysis&Elaboration进行编译,分析检查输入文件是否有错误。

2.创建仿真波形文件

a.点击New—Vector Waveform File—save as

基于FPGA的数字电子时钟设计与实现

图6 新建仿真波形文件图

b.在Name框图中右击鼠标,Insert—Insert Node or Bus—Node Finder—在Filter中选择Pinns:all,点击list,点击“》”将左侧列表中的内容移动到右侧列表中。

基于FPGA的数字电子时钟设计与实现

图7 插入管脚图

c.在CP上右击选择value,选择时钟脉冲信号clock(周期可自行设置)。EN 和nCR都选择高电平(Forcing High)。

基于FPGA的数字电子时钟设计与实现

图8 输入信号赋值

d.选择Assignments—Settings设置—simulater settings—模式mode选择功能型Functional

e.选择Processing—generate functional simulation netlist生成功能网表

基于FPGA的数字电子时钟设计与实现

图9 生成功能网表图

f.点击波形仿真的快捷键,进行波形的仿真。

g.分别给EN和nCR不同的电平信号,观察分析波形的变化。

基于FPGA的数字电子时钟设计与实现

图10 EN=1 nCR=1

基于FPGA的数字电子时钟设计与实现

图11 EN=0 nCR=1

基于FPGA的数字电子时钟设计与实现

图12 EN=1 nCR=0

基于FPGA的数字电子时钟设计与实现

图13 EN=0 nCR=0

基于FPGA的数字电子时钟设计与实现

图14 EN脉冲 nCR=1

2.2工作原理及系统框图

利用数字电子技术、EDA设计方法、FPGA等技术,设计、仿真并实现一个基于FPGA的数字电子时钟基本功能,其基本组成框图如图1所示,振荡器采用ALTERA的DE2-70实验板的50MHz输出,分频器将50MHz的方波进行分频进而得到1Hz的标准秒脉冲,时、分、秒计时模块分别由二十四进制时计数器、六十进制分计数器和六十进制秒计数器完成,校时模块完成时和分的校正。电子时钟扩展功能为倒计时流水灯。数字电子钟的电路组成框图片如下图:

多功能数字钟顶层模块倒计时模块时计数器(24进制)

校时电路分频器

分计数器(60进制)

秒计数器(60进制)

6计数器10计数器时译码显示分译码显示6计数器10计数器分译码显示

CP 1Hz

振荡器

图15 系统框图

1.数字钟电路系统由主体电路和扩展电路两大部分所组成。

2. 数字电子时钟电路具有时、分、秒计时,秒计数器计满60后向分计数器进位,分计数器计满60后向小时计数器进位,小时计数器按照“24进制”规律计数。

3. 准确计时,以数字形式显示时、分、秒的时间,计数器的输出经译码器送显示器。

4. 具有分、时校正功能,校正输入脉冲频率为1Hz

5. 复位功能,时、分、秒计时清零。

6.扩展功能为:具有仿广播电台整点报时的功能,即每逢59分51秒、52秒、53秒、54秒、55秒及57秒,LED 绿灯依此点亮,59分59秒时,LED 红灯亮,形成倒计时流水灯报时。

三.软件方案

3.1 程序流程图

3.1.1 24进制

小时采用24进制计时,当CP ↑,EN 和nCR 为高电平时计数,计数范围为[0,23],使能信号EN 等于0时,计时器保持。当高位大于2或高位等于2且低位大于3时,计时器清零,否则继续计时。流程图见下图。

开始

CP ↑or nCR ↓

nCR=0 ?

清零EN=0 ?

保持QH>2 or Q>23

清零Q=Q+1

N

Y

Y

Y

Y

N

N

N

图16 24进制程序流程图

3.1.2 10进制流程图

当CP ↑,EN 和nCR 为高电平时计数,计数范围为[0,9],使能信号EN 等于0时,计时器保持。当计时到9的时候,计时器清零,否则继续计时。流程图见下图。

开始

CP ↑or nCR ↓

nCR=0 ?

清零

EN=0 ?保持

Q=9 ?

清零

Q=Q+1

N

Y Y

Y

Y

N

N

N

图17 10进制流程图

3.1.3 6进制

当CP ↑,EN 和nCR 为高电平时计数,计数范围为[0,5],使能信号EN 等于0时,计时器保持。当计时到5的时候,计时器清零,否则继续计时。流程图见下图。

开始

CP ↑or nCR ↓

nCR=0 ?

清零EN=0 ?

保持Q=5 ?清零Q=Q+1

N

Y

Y

Y

Y

N

N

N

图18 6进制流程图

3.1.4 60进制

分、秒采用60进制计时,当CP ↑,EN 和nCR 为高电平时计数,计数范围为[0,59],使能信号EN 等于0时,计时器保持。当个位等于9时向十位进位;当个位等于9十位等于5,计时器清零,否则继续计时。流程图见下图。

开始

CP ↑or nCR ↓

nCR=0?

清零N 个位Q1=9?

Q1=Q1+1

Q2=Q2+1Q2=5?Q1=9?

清零

Q1=Q1+1

EN=0?保持N

Y

N

N

Y

N Y Y N

图19 60进制流程图

3.1.5 from0to9

数码管有7段组成,分共阳极和共阴极,本次设计采用共阳极数码管。当输入为低电平时,数码管显示;当输入为高电平时,数码管不显示。用这样的方法输入不同的高低信号控制数码管的显示。

开始

Case D HEX=7'b1111111

HEX=b0010010HEX=7'b0000110HEX=7'b0001111HEX=7'b0100000

HEX=7'b0100100

HEX=7'b1001100

HEX=7'b0000001HEX=7'b0000100

HEX=1001111HEX=7'b0000000显示0显示1显示2显示3显示4

显示5显示6

显示7显示8显示9N

Y

图20 from0to9流程图

3.1.6 分频模块

开始

50MHz 方波

0.5Hz 方波

50Hz 方波

5KHz 方波

500KHz 方波

10^2分频

10^2分频

10^2分频

10^2分频

图21 分频模块流程图

3.1.7 总流程图

开始

开始CP ↑or nCR ↓CP ↑or nCR ↓AdjHrkey=1?

AdjHrkey=1?时低位=9?

时低位=9?低位清零高位进位低位清零高位进位高位>2or 时>23

高位>2or 时>23清零

清零低位计数

低位计数AdjMinKey=1?

AdjMinKey=1?秒低位=9?秒低位=9?低位清零高位进位

低位清零高位进位低位计数

低位计数秒高位=5?

秒高位=5?秒高位清零,分低位进位

秒高位清零,分低位进位高位计数

高位计数分低位=9?

分低位=9?低位清零高位进位

低位清零高位进位低位计数

低位计数高位=5?

高位=5?清零

清零高位计数

高位计数分低位=9?

分低位=9?低位清零高位进位

低位清零高位进位分高位=5?

分高位=5?分清零,时低位位进位

分清零,时低位位进位高位计数

高位计数时低位=9?

时低位=9?高位>2or 时>23

高位>2or 时>23清零清零低位计数

低位计数低位清零高位进位

低位清零高位进位低位计数

低位计数N

N

Y

Y

N

N Y

Y

N

N

N

N Y

Y

N

N

Y

Y

N

N

N

N

Y

Y

N

N Y

Y Y

Y N

N

Y

Y

N

N

Y

Y

Y

Y N

N N

N

Y

Y

Y

Y

N

N Y Y

分频模块

图22 总流程图

3.2 程序清单

3.2.1头文件complete_clock程序

module complete_clock(HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,_50MHzIn,_1Hz,_50Hz,

_5KHz,_500KHz,AdjMinkey,AdjHrkey,nCR,Alarm,LED0,LED10,LED3,LED4,LED5,LED6,LED 7,LED8,LED9);

output [7:0] HEX0,HEX1,HEX2,HEX3,HEX4,HEX5;

output Alarm,_1Hz,_50Hz,_5KHz,_500KHz;

output LED0;

output LED10;

output LED3;

output LED4;

output LED5;

output LED6;

output LED7;

output LED8;

output LED9;

wire [7:0] HEX0,HEX1,HEX2,HEX3,HEX4,HEX5;

input nCR,_50MHzIn;

wire _1Hz,_50Hz,_5KHz,_500KHz;

wire LED0;

wire LED10;

wire LED3;

wire LED4;

wire LED5;

wire LED6;

wire LED7;

wire LED8;

wire LED9;

input AdjMinkey,AdjHrkey;

wire [7:0] Second,Minute,Hour;

Divided_Frequency C1(_5KHz,_500KHz,nCR,_50MHzIn);//调用分频模块,输入50MHz的

频率,经两次分频后变为5KHz Divided_Frequency U0(_1Hz,_50Hz,nCR,_5KHz);//调用分频模块,输入5KHz的频率,经

两次分频后变为1Hz

top_clock U1(Hour,Minute,Second,_1Hz,nCR,AdjMinkey,AdjHrkey);//调用校时模块,

对时、分模块进行校时baoshi U2(Alarm_Ring,Minute,Second,_50Hz,_5KHz);

assign Alarm=Alarm_Ring;

assign LED0=({Minute,Second}==16'h5951);//定义LED0为59分51秒时灯亮

assign LED10=({Minute,Second}==16'h5952);//定义LED10为59分52秒时灯亮

assign LED3=({Minute,Second}==16'h5953);//定义LED3为59分53秒时灯亮

assign LED4=({Minute,Second}==16'h5954);//定义LED4为59分54秒时灯亮

assign LED5=({Minute,Second}==16'h5955);//定义LED5为59分55秒时灯亮

assign LED6=({Minute,Second}==16'h5956);//定义LED6为59分56秒时灯亮

assign LED7=({Minute,Second}==16'h5957);//定义LED7为59分57秒时灯亮

assign LED8=({Minute,Second}==16'h5958);//定义LED8为59分58秒时灯亮

assign LED9=({Minute,Second}==16'h5959);//定义LED9为59分59秒时灯亮

from0to9 U10(HEX0,Second[3:0]); //个位秒调用译码

from0to9 U9(HEX1,Second[7:4]); //十位秒调用译码

from0to9 U3(HEX2,Minute[3:0]); //个位分调用译码

from0to9 U4(HEX3,Minute[7:4]); //个位分调用译码

from0to9 U5(HEX4,Hour[3:0]); //个位时调用译码

from0to9 U6(HEX5,Hour[7:4]); //十位时调用译码

endmodule

3.2.2 counter24程序

module counter24(CntH,CntL,nCR,EN,CP);

input CP,nCR,EN;

output [3:0] CntH,CntL;

reg [3:0] CntH,CntL;

always @(posedge CP or negedge nCR)

begin

if(~nCR) {CntH,CntL}<=8'h00;//当nCR=0时,计时器清零

else if(~EN) {CntH,CntL}<={CntH,CntL};//当EN=0时,停止计时,保持

else if((CntH>2)||(CntH>9)||((CntH==2)&&(CntL>=3)))

{CntH,CntL}<=8'h00;

else if((CntH==2)&&(CntL<3))

begin CntH<=CntH;CntL<=CntL+1'b1;end

else if(CntL==9)

begin CntH<=CntH+1'b1;CntL<=4'b0000;end

else

begin CntH<=CntH;CntL<=CntL+1'b1;end

end

Endmodule

3.2.3 counter60程序

module counter60(Q1,Q2,Q3,Q4,Q5,Q6,Cnt,Cnt1,Cnt24,nCR,EN,CP,LED,LED1,LED2); input CP,nCR,EN;

output [7:0] Cnt;

output [7:0] Cnt1;

output [7:0] Cnt24;

output [6:0] Q1;

output [6:0] Q2;

output [6:0] Q3;

output [6:0] Q4;

output [6:0] Q5;

output [6:0] Q6;

output LED;

output LED1;

output LED2;

wire [7:0] Cnt;

wire [7:0] Cnt1;

wire [7:0] Cnt24;

wire [6:0] Q1;

wire [6:0] Q2;

wire [6:0] Q3;

wire [6:0] Q4;

wire [6:0] Q5;

wire [6:0] Q6;

wire LED;

wire LED1;

wire LED2;

wire ENP;

wire ENP1;

wire ENP2;

wire ENP3;

counter10 UC0(Cnt[3:0],nCR,EN,CP);

counter6 UC1(Cnt[7:4],nCR,ENP,CP);

counter10 UC2(Cnt1[3:0],nCR,ENP1,CP);

counter6 UC3(Cnt1[7:4],nCR,ENP2,CP);

counter24 UC4(Cnt24[7:4],Cnt24[3:0],nCR,ENP3,CP);

assign ENP=(Cnt[3:0]==4'h9);

assign ENP1=(Cnt==8'h59);

assign ENP2=((Cnt1[3:0]==4'h9)&&(Cnt==8'h59));

assign ENP3=((Cnt1==8'h59)&&(Cnt==8'h59));

assign LED=~CP;

assign LED1=~CP;

assign LED2=~CP;

from0to9 UC5(Q1,Cnt[3:0]);

from0to9 UC6(Q2,Cnt[7:4]);

from0to9 UC7(Q3,Cnt1[3:0]);

from0to9 UC8(Q4,Cnt1[7:4]);

from0to9 UC9(Q5,Cnt24[3:0]);

from0to9 UC10(Q6,Cnt24[7:4]);

Endmodule

3.2.4 from0to9程序

module from0to9(HEX,D);

output [6:0] HEX;

input [3:0] D;

reg [6:0] HEX;

always @(D)

begin

case(D)

4'd0:{HEX[0],HEX[1],HEX[2],HEX[3],HEX[4],HEX[5],HEX[6]}=7'b0000001; 4'd1:{HEX[0],HEX[1],HEX[2],HEX[3],HEX[4],HEX[5],HEX[6]}=7'b1001111; 4'd2:{HEX[0],HEX[1],HEX[2],HEX[3],HEX[4],HEX[5],HEX[6]}=7'b0010010;

相关推荐
相关主题
热门推荐