基于FPGA的数字时钟设计---三峡大学电气与新能源学院.doc
《基于FPGA的数字时钟设计---三峡大学电气与新能源学院.doc》由会员分享,可在线阅读,更多相关《基于FPGA的数字时钟设计---三峡大学电气与新能源学院.doc(15页珍藏版)》请在冰豆网上搜索。
《CPLD及电子CAD》
同组同学:
代磊
一.EDA介绍
EDA技术就是以计算机为工具,设计者在EDA软件(MAX+plusII或QuartusII)平台上,用硬件描述语言VHDL或相关类似编程语言完成设计文件,然后由计算机自动地完成逻辑编译、化简、分割、综合、优化、布局、布线和仿真,直至对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。
EDA技术的出现,极大地提高了电路设计的效率和可操作性,减轻了设计者的劳动强度。
二.VHDL语言
(1)VHDL语言介绍:
VHDL主要用于描述数字系统的结构,行为,功能和接口。
除了含有许多具有硬件特征的语句外,VHDL的语言形式和描述风格与句法是十分类似于一般的计算机高级语言。
(2)VHDL语言的基本知识:
(a)实体,构造体
Entity(实体)用来说明模型的外部输入输出特征;Architecture(构造体)用来定义模型的内容和功能
每一个构造体必须有一个实体与它相对应,所以两者一般成对出现
(b).顺序语句和并行语句
顺序语句只能出现在进程(Process)和子程序中,其中子程序包括函数(Function)和过程(Procedure).顺序语句种类有:
进程语句,赋值语句,流程控制语句,等待语句,子程序调用语句,返回语句,空操作语句。
(具体例子见后面设计的系统示例中)。
并行语句是VHDL区别于传统软件描述语言最显著的一个方面.各种并行语句在结构体中是同时并发执行的,也就是说,只要某个信号发生变化,都会引起相应语句被执行而产生相应的输出,其执行顺序与书写顺序没有任何关系。
但在一个结构体内,各进程外部的语句是并发执行的,它们之间可以通过信号进行通信,而每个进程内部的语句是顺序执行的。
(相关例子也在后面列的设计例子中有)
在实际编程时,应将并行语句和顺序语句灵活运用才符合VHDL的设计要求和硬件特点。
(c)进程
两种进程设计方式:
****************************************************************************
【进程标号:
】process【(敏感参数列表)】[is]
[进程申明部分;]
begin
顺序语句
endprocess
****************************************************************************
【进程标号:
】process[is]
[进程申明部分;]
begin
wait语句;
顺序语句
endprocess
*******************************************************************************
(d)信号与变量
信号与变量的区别见下面图表:
(e)顺序语句
IF_THEN_ELSE语句
只能在进程内使用,至少应有一个条件句,条件句必须由布尔表达式构成。
语句形式:
IF条件句Then
顺序语句
ELSIF条件句Then
顺序语句
ELSE
顺序语句
ENDIF
CASE_WHEN语句
表达式可以是一个整数类型或枚举类型的值,也可以是由这些数据类型的值构成的数组,条件句中的选择值必在表达式的取值范围内。
除非所有条件句中的选择值能完整覆盖CASE语句中表达式的取值,否则最末一个条件句中的选择必须用“OTHERS”表示。
CASE语句中每一条件句的选择值只能出现一次,不能有相同选择值的条件语句出现。
CASE语句执行中必须选中,且只能选中所列条件语句中的一条。
LOOP语句
基本格式:
[LOOP标号:
]
[重复模式]LOOP
顺序语句;
ENDLOOP[LOOP标号]
FOR<条件表达式>IN<范围>LOOP
顺序语句
ENDLOOP;
WHILE<条件表达式>LOOP
顺序语句
ENDLOOP;
[LOOP标号:
]LOOP
顺序语句
EXIT[LOOP标号];
ENDLOOP;
NEXT
[LOOP标号][WHEN语句]
2、并行语句
VHDL语言与传统软件描述语言最大的不同,有多种语句格式,包括:
并行信号赋值语句、进程语句、块语句、条件信号赋值语句、元件例化语句、生成语句、并行过程调用语句。
各种并行语句在结构体中的执行是同步进行的,或者说是并行运行的,其执行方式与书写的顺序无关。
在执行中,并行语句之间可以有信息往来,也可以是互为独立、互不相关、异步运行的(如多时钟情况)。
每一并行语句内部的语句运行方式可以有两种不同的方式,即并行执行方式(如块语句)和顺序执行方式(如进程语句)
With_Select_Then选择信号语句
所有的“WHEN”子句必须是互斥的。
一般用“WhenOthers”来处理未考虑到的情况,只有一个参考信号和赋值符(<=),每一子句结尾是逗号,最后一句是分号
When_Else选择信号语句
根据指定条件对信号赋值,条件可以为任意表达式;根据条件的出现的先后次序隐含优先权;最后一个ELSE子句隐含了所有未列出的条件。
每一子句的结尾没有标点,只有最后一句有分号
3、进程语句
进程语句是VHDL中最重要的语句,具有并行和顺序行为的双重性。
进程和进程语句之间是并行关系,进程内部是一组连续执行的顺序语句,进程语句与构造体中的其余部分进行信息交流是靠信号完成的。
基本格式:
[进程标号:
]PROCESS[(信号敏感表)]IS
〈说明区〉
BEGIN
〈顺序语句〉
ENDPROCESS[进程标号];
信号敏感表
进程赖以启动的是敏感表。
对于表中列出的任何信号的改变,都将启动进程,执行进程内相应顺序语句。
一些VHDL综合器,综合后,对应进程的硬件系统对进程中的所有输入的信号都是敏感的,不论在源程序的进程中是否把所有的信号都列人敏感表中。
为了使软件仿真与综合后的硬件仿真对应起来,应当将进程中的所有输人信号都列入敏感表中
双向口
双口RAM的输入和输出是相互独立的吧,他们的工作是分别由(输入始能,输入时钟,输入地址)和(输出始能,输出时钟,输出地址)控制了,只要注意,同时不对一个地址进行读写操作,就应该不会出问题。
以下是课堂上双向口示例程序:
ENTITYldcntISPORT( clk,ld,oe:
INstd_logic;
count:
INOUTstd_logic_vector(7DOWNTO0));
ENDldcnt;
ARCHITECTUREarchldcntOFldcntIS
SIGNALint_count:
std_logic_vector(7DOWNTO0);
BEGIN
cnt:
PROCESS(clk)
BEGIN
IFrising_edge(clk)THEN
IFld='1'THEN int_count<=count;
ELSEint_count<=int_count+1;
ENDIF;
ENDIF;
ENDPROCESScnt;
outen:
PROCESS(oe,int_count)BEGIN
IFoe='1'THENcount<=int_count;
ELSEcount<=(OTHERS=>'Z');
ENDIF;
ENDPROCESSouten;
ENDarchldcnt;
状态机
所谓状态机(FSM有限状态机),简单来讲,就是给个条件,由这个状态跳到下一个,或者保持不变。
在此过程中有可能有某些值得输出。
一个最简单的状态机例子:
A—》B—》C—》A,每来一个时钟,状态改变一下。
(a)状态机的优势:
1、状态机克服了纯硬件数字系统顺序方式控制不灵活的缺点。
2、由于状态机的结构相对简单,设计方案相对固定。
3、状态机容易构成性能良好的同步时序逻辑模块。
4、高可靠性。
5、在高速运算和控制方面,状态机更有其巨大的优势。
6、状态机的VHDL表述丰富多样、有其独到的好处。
(后面数字时钟设计中对数码管的显示切换就是用状态机的设计原理完成的)
(b)状态机结构
说明部分:
定义枚举型数据类型,定义状态变量。
主控时序进程:
主控时序进程主要负责状态机运转和在时钟驱动下负责状态的转换。
:
主控组合进程:
也称为状态译码进程,其任务是根据外部输入的控制信号,或和当前状态的状态值确定下一状态的取向,以及确定相应的输出。
辅助进程:
用于配合状态机工作的组合或时序进程。
元件例化
元件例化即生成在新图形文件中能被应用到的图形设计文件。
此次试验主要涉及到具体操作问题。
下面就相关操作予以说明:
1选择工具按钮有效时,在图形编辑器窗口的空白处单击鼠标左键以确定输入位置,然后选择EnterSymbol,或双击鼠标左键。
2将出现一个EnterSymbol对话框,在symbolLibraries框中选择“..\maxplus2\max2lib\prim”。
3所有的Altera图元以列表方式显示出来,选择您想输入的图元,然后选择OK
(后面数字时钟设计中的图形文件的制作主要就是用此法,并连线才构成一个最终的时钟系统)
三.数字钟综合设计
一.系统总体框图
时间模块
时间clk—1HZ
或
整点报时
蜂鸣器
8位数码管显示
秒表clk—3MHZ
秒表模块
定时模块
定时比较和显示切换
8个数码管以不同形式不同频率闪烁
3分频
蜂鸣器clk
2分频
闹钟分段
二.系统文件截图
三.各模块部分介绍
(1)时钟和调时部分——24,60进制计数
(a)模块截图:
(b)程序
24进制:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityershisi_33_34is
port(clk,clr,en:
instd_logic;
carry:
outstd_logic;
ge:
outstd_logic_vector(3downto0);
shi:
outstd_logic_vector(3downto0));
end;
architectureoneofershisi_33_34is
signalg,s:
std_logic_vector(3downto0);
begin
process(clk,clr,en,g,s)
begin
ifclr='1'then
g<="0000";s<="0000";
elsi