现代电子实验报告电子科技大学.docx
《现代电子实验报告电子科技大学.docx》由会员分享,可在线阅读,更多相关《现代电子实验报告电子科技大学.docx(31页珍藏版)》请在冰豆网上搜索。
现代电子实验报告电子科技大学
基于FPGA的现代电子实验设计报告
——数字式秒表设计(VHDL)
学院:
物理电子学院
专业:
学号:
学生姓名:
指导教师:
刘曦
实验地点:
科研楼303
实验时间:
摘要:
通过使用VHDL语言开发FPGA的一般流程,重点介绍了秒表的基本原理和相应的设计方案,最终采用了一种基于FPGA的数字频率的实现方法。
该设计采用硬件描述语言VHDL,在软件开发平台ISE上完成。
该设计的秒表能准确地完成启动,停止,分段,复位功能。
使用ModelSim仿真软件对VHDL程序做了仿真,并完成了综合布局布线,最终下载到EEC-FPGA实验板上取得良好测试效果。
关键词:
FPGA,VHDL,ISE,ModelSim
绪论.........................................................4
第一章实验任务…………………………………..5
第二章系统需求和解决方案计划………..5
第三章设计思路…………………………………..6
第四章系统组成和解决方案………………..6
第五章各分模块原理……………………………8
第六章仿真结果与分析………………………..11
第七章分配引脚和下载实现…………………13
第八章实验结论…………………...………………14
绪论:
1.1课程介绍:
《现代电子技术综合实验》课程通过引入模拟电子技术和数字逻辑设计的综合应用、基于MCU/FPGA/EDA技术的系统设计等综合型设计型实验,对学生进行电子系统综合设计与实践能力的训练与培养。
通过《现代电子技术综合实验》课程的学习,使学生对系统设计原理、主要性能参数的选择原则、单元电路和系统电路设计方法及仿真技术、测试方案拟定及调测技术有所了解;使学生初步掌握电子技术中应用开发的一般流程,初步建立起有关系统设计的基本概念,掌握其基本设计方法,为将来从事电子技术应用和研究工作打下基础。
本文介绍了基于FPGA的数字式秒表的设计方法,设计采用硬件描述语言VHDL,在软件开发平台ISE上完成,可以在较高速时钟频率(48MHz)下正常工作。
该数字频率计采用测频的方法,能准确的测量频率在10Hz到100MHz之间的信号。
使用ModelSim仿真软件对VHDL程序做了仿真,并完成了综合布局布线,最终下载到芯片Spartan3A上取得良好测试效果。
1.2VHDL语言简介:
VHDL的英文全名是Very-High-SpeedIntegratedCircuitHardwareDescriptionLanguage,诞生于1982年。
1987年底,VHDL被IEEE和美国国防部确认为标准硬件描述语言。
VHDL主要用于描述数字系统的结构,行为,功能和接口。
除了含有许多具有硬件特征的语句外,VHDL的语言形式和描述风格与句法是十分类似于一般的计算机高级语言。
VHDL的程序结构特点是将一项工程设计,或称设计实体(可以是一个元件,一个电路模块或一个系统)分成外部(或称可视部分,及端口)和内部(或称不可视部分),既涉及实体的内部功能和算法完成部分。
在对一个设计实体定义了外部界面后,一旦其内部开发完成后,其他的设计就可以直接调用这个实体。
这种将设计实体分成内外部分的概念是VHDL系统设计的基本点。
VHDL语言的特点:
VHDL语言能够成为标准化的硬件描述语言并获得广泛应用,它自身必然具有很多其他硬件描述语言所不具备的优点。
归纳起来,VHDL语言主要具有以下优点:
(1)VHDL语言功能强大,设计方式多样
(2)VHDL语言具有强大的硬件描述能力
(3)VHDL语言具有很强的移植能力
(4)VHDL语言的设计描述与器件无关
(5)VHDL语言程序易于共享和复用
由于VHDL语言是一种描述、模拟、综合、优化和布线的标准硬件描述语言,因此它可以使设计成果在设计人员之间方便地进行交流和共享,从而减小硬件电路设计的工作量,缩短开发周期。
1.3FPGA简介
FPGA(Field-ProgrammableGateArray),即现场可编程门阵列,它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。
它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。
以硬件描述语言(Verilog或VHDL)所完成的电路设计,可以经过简单的综合与布局,快速的烧录至FPGA上进行测试,是现代IC设计验证的技术主流。
这些可编辑元件可以被用来实现一些基本的逻辑门电路(比如AND、OR、XOR、NOT)或者更复杂一些的组合功能比如解码器或数学方程式。
在大多数的FPGA里面,这些可编辑的元件里也包含记忆元件例如触发器(Flip-flop)或者其他更加完整的记忆块。
系统设计师可以根据需要通过可编辑的连接把FPGA内部的逻辑块连接起来,就好像一个电路试验板被放在了一个芯片里。
一个出厂后的成品FPGA的逻辑块和连接可以按照设计者而改变,所以FPGA可以完成所需要的逻辑功能。
FPGA一般来说比ASIC(专用集成电路)的速度要慢,实现同样的功能比ASIC电路面积要大。
但是他们也有很多的优点比如可以快速成品,可以被修改来改正程序中的错误和更便宜的造价。
厂商也可能会提供便宜的但是编辑能力差的FPGA。
因为这些芯片有比较差的可编辑能力,所以这些设计的开发是在普通的FPGA上完成的,然后将设计转移到一个类似于ASIC的芯片上。
另外一种方法是用CPLD(ComplexProgrammableLogicDevice,复杂可编程逻辑器件)。
FPGA设计流程:
对于目标文件为FPGA的HDL设计,其一般流程如下:
1、文本编辑
用任何文本编辑器都可以进行,通常VHDL文件保存为vhd文件,Verilog文件保存为v文件。
2、使用编译工具编译源文件
HDL的编译器有很多,ACTIVE公司,MODELSIM公司,SYNPLICITY公司,SYNOPSYS公司,VERIBEST公司等都有自己的编译器。
3、逻辑综合
将源文件调入逻辑综合软件进行综合。
综合的目的是在于将设计的源文件由语言转换为实际的电路。
但是此时还没有在芯片中形成真正的电路。
这一步的最终目的是生成门电路级的网表(Netlist)。
4、布局、布线
将第3步生成的网表文件调入PLD厂家提供的软件中进行布线,即把设计好的逻辑安放到CPLD/FPGA内。
这一步的目的是生成用于下载(编程Programming)的编程文件。
在这一步,将用到第3步生成的网表,并根据CPLD/FPGA厂商的器件容量,结构等进行布局、布线。
这就好像在设计PCB时的布局布线一样。
先将各个设计中的门根据网表的内容和器件的结构放在器件的特定部位。
然后,在根据网表中提供的各门的连接,把各个门的输入输出连接起来。
最后,生成一个供编程的文件。
这一步同时还会加一些时序信息(Timing)到你的设计项目中去,以便于你做后仿真。
5、后仿真
利用在布局布线中获得的精确参数,用仿真软件验证电路的时序。
(也叫布局布线仿真或时序仿真)。
这一步主要是为了确定你的设计在经过布局布线之后,是不是还满足你的设计要求。
6、编程,下载
如果前几步都没有发生错误,并且符合设计要求,这一步就可以将由适配器等产生的配置或下载文件通过编程器或下载电缆下载到目标芯片中。
7、硬件测试
硬件测试的目的是为了在更真实的环境中检验HDL设计的运行情况,特别是对于HDL程序设计上不是十分规范,语义上含有一定歧义的程序。
一、实验任务——设计一个秒表:
秒表的计时范围为00’00”00~59’59”99。
有两个按钮开关Start/Stop和Split/Reset,控制秒表的启动、停止、分段和复位:
1,在秒表已经被复位的情况下,按下“Start/Stop”键,秒表开始计时。
2,在秒表正常运行的情况下,如果按下“Start/Stop”键,则秒表暂停计时。
3,再次按下该键,秒表继续计时。
4,在秒表正常运行的情况下,如果按下“Split/Reset”键,显示停止在按键时的时间,但秒表仍然在计时;
5,再次按下该键,秒表恢复正常显示。
6,在秒表暂停计时的情况下,按下“Split/Reset”键,秒表复位归零。
二、系统需求和解决方案计划:
在项目开始设计时,首先要确定系统的需求并发展出一个针对这些需求的计划。
按照秒表的设计要求,整个电路需要下面这些组成部分:
2.1分频器:
对晶体振荡器产生的时钟信号进行分频,产生时间基准信号。
2.2计数器:
对时间基准脉冲进行计数,完成计时功能。
2.3数据锁存器:
锁存数据使显示保持暂停。
2.4控制器:
控制计数器的运行、停止以及复位产生锁存器的使能信号。
2.5扫描显示的控制电路:
包括扫描计数器、数据选择器和7段译码器,控制8个数码管以扫描方式显示计时结果。
2.6按键消抖电路:
消除按键输入信号抖动的影响,输出单脉冲。
三、设计思路:
从FPGA开发板的电路可以看出,其不具备对按键输入的消抖功能,故须编写消抖功能的模块代码。
消除按键抖动的影响;每按一次键,只输出一个脉冲,其宽度为一个时钟周期。
由开发板电路结构可以看出,其为共阳结构,故在其运行为低有效。
8个数码显示管共用一个段位,故为了将时钟显示在8个数码管上,需要一定频率(本秒表为1KHz)的信号进行扫描,使得我们肉眼看上去是8个数码管同时显示的。
为了实现秒表暂停和复位的功能,需要锁存器模块将时钟数据锁存起来,并且结合控制电路满足秒表的功能。
FPGA开发板的晶振频率为48MHz,而实际电路需要的频率为1KHz,故须建立分频模块,将48MHz的晶振频率分频成1KHz。
在构建计数范围从00’00”00-59’59”99的秒表时,从数码管显示的角度可知,需要建立模六和模十两种计数模块进行组合形成。
设计图如下:
四、系统组成和解决方案:
在项目开始设计时,首先要确定系统的需求并发展出一个针对这些需求的计划。
按照数字式秒表工作原理的描述,需要下面这些主要的子系统:
1,控制电路;
2,由石英振荡器和数字分频器构成的时基信号发生器;
3,按键开关(按键消抖);
4,计数器;
5,数据锁存器;
6,扫描显示的控制子系统(包括显示译码和扫描控制);
7,六个数码管(LED显示电路)。
设计框图如下:
五、各分模块原理:
5.1、48M-1K分频器
对晶振振荡器产生的时钟信号进行分频,产生时间基准信号。
由于FPGA开发板的晶振频率为48MHz,故在设计分频器模块时,为了将频率分频成1KHz,即将输入的信号源每48000个周期转换成输出的一个周期。
因此利用上升沿计数手段,将0-47999用16位二进制数表示,而在从0-47999的计数过程中,该二进制数的最高位只有一次状态变化,故可取对应二进制数的最高位来输出达到分频到1KHz的目的。
如下代码为将晶振振荡器48MHz频率分频成1KHz信号:
5.2、计数器
对时间基准脉冲进行计数,完成计时功能。
实现数字秒表的设计需要模6和模10计数器进行组合。
考虑到秒表的暂停和清零等功能,在设计计数器模块时,必须有时钟输入端、使能以及清零端。
在有时钟信号输入的情况下,当使能端无效时,计数器不能进行计数;当清零端有效时,计数重新归为0值。
而为了实现计数的目的,故必须将各个计数器级联来实现从00’00”00-59’59”99的计数,使得级联的各技术模块有共同的清零端与使能端,因此该单个模块需要有输出进位以及该时刻的计数值并且前一级的进位端连在下一级的使能端上。
如下为模6和模10计数器代码:
为了实现在秒表计数是0-5的计数部分,故须设计一个模6计数器,输入时钟信号、使能和清零,遇上升沿则记一次数,当从0记到5时,进位端(用于与下一级计数器级联)有效,且遇上升沿后从5变到0,并且输出的还有每一时刻的计数值。
为了实现在秒表计数是0-9的计数部分,故须设计一个模10计数器,输入时钟信号、使能和清零,遇上升沿则记一次数,当从0记到9时,进位端(用于与下一级计数器级联)有效,且遇上升沿后从9变到0,并且输出的还有每一时刻的计数值。
5.3、控制电路
控制计数器的运行、暂停以及复位;产生锁存器的使能信号。
从如下状态图可知,在设计控制模块时,为实现开发板上控制秒表的运行暂停和清零功能,必须设置两个控制输入端,以及需要时钟信号输入端。
在时钟信号输入情况下,由状态图显示,在输入不同的控制信号是,控制模块需输出信号控制计数器及其他各模块的清零和使能端,即当外部控制运行/暂停键首次按下时,控制模块输出控制技术模块最开始的计数器模块使能有效,各模块清零无效;当第二次按下时为暂停信号,控制模块控制锁存器锁存并控制显示。
当清零控制键按下时,控制模块控制技术模块清零,故要两个输出使能端。
5.4、锁存器
锁存数据,使显示保持锁定。
为达到锁存数据目的,则必须要有对应的8个数码显示数据输入,当其中两个数码数据为不变的,故只需输入6组由4位二进制码构成的数据、1KHz时钟信号以及控制模块作用的使能端。
当使能端有效的情况下,将输入6组数据输出。
5.5、消抖电路
消除按键输入信号抖动的影响,输出单脉冲。
在手动控制按键输入控制信号前,由于人为因素,会导致输入信号不稳定等问题,故须添加一个消抖模块,使得每次按键只会产生一个脉冲。
故除1KHz时钟信号输入外,还需要一个按键控制信号输入端以及一个按键消抖后输出信号。
5.6、译码器
包括扫描计数器、3-8译码器、数据选择器以及7段译码器;控制8个数码管一扫描方式显示计时结果。
译码模块的功能是对之前计数模块的计数值进行译码,使其可以在数码管上显示出来。
在8个数码管中有两个数码管显示是不变的,故不需要输出,所以译码模块要求输入需要译码的6组数据以及1KHz时钟信号。
译码模块除了要求对每一个可能的值(0-9)进行译码外,还有设计要求8个数码管显示共用一个段位,故还需设计一个3-8译码模块对8个数码显示管进行选择,使其轮流显示,在1KHz的扫描下,使人看上去是8个数码管同时显示的。
l
5.7、计数器模块
由模6和模10计数器级联而成。
为了实现从00’00”00-59’59”99的计数,需要将4个模10计数模块和2个模6计数模块级联,并且为了达到设计要求是这6个计数器工作在100Hz的时钟信号下,可利用一个模10的计数模块对1KHz进行分频,输出的信号频率即为100Hz,该总计数模块最终需输出6组计数数据以及其最终的进位。
5.8、top文件
由以上各个文件相互连接而成,以及硬件的管脚管脚分布。
将之前所建立的各个模块级联起来,从按键输入信号到按键消抖模块再进而连接到控制器,通过控制模块对总计数器模块、锁存器模块、译码器模块、分频器模块相互连接起来,并设置晶振输入信号以及两个按键控制信号输入,再由译码器模块知,秒表设计的最终输出由一个3-8对应的8位位选信号和一组7位的段选信号组成。
最后对总文件的输出进行管脚分配,并下载到FPGA开发板上验证设计。
六、仿真结果与分析:
:
6.11000HZ信号的产生
6.210位计数器的产生
由图可得,10位计数器从0000计到1001
6.36位计数器的产生
由图可得,6位计数器从0000计到0101。
6.4七段数码管显示数字
6.5锁存器
由图可得,当没有时钟信号时Q不变。
6.6分频器1000Hz-100Hz
七、分配引脚和下载实现:
全部仿真通过后,就运行ISE的设计实现,然后再打开XILINXPACE,在里面分配引脚,即实现设计的输入输出端口与实际芯片的输入输出端口的对应连接。
比如七段LED管的控制信号就连接到实际电路的七个引脚。
需要注意的是一些端口是固定的,不能胡乱的连接。
比如时基信号即石英振荡器所提供的信号就只能由P181
输入。
同时还要考虑内部的可配制逻辑块CLB的数量是否够满足程序的综合要求。
一切都准备就绪后就可以运行ConfigureDevice,选择要下载的位文件(.bit)便可开始。
八、实验结论:
8.1、本次实验实现了秒表的计数,复位,暂停,锁显等功能,让我充分了解和认识到ISE和Modelsim软件的强大功能和FPGA技术的优越性。
并对软件开发产生了兴趣。
8.2、仿真和下载实现是两个不同的检验,仿真从软件内部来检验程序的合理性和正确性,准确性较高。
而下载实现是从外部来观察程序的实现效果,更直观,但不具有准确性。
8.3、有时候下载实现了所有的功能,但是仿真通不过,这可能是因为程序中有些部分并不完善导致。
从外部来看,效果是一样的,但实际程序却存在漏洞。
附:
参考文献:
《数字设计原理与实践》作者:
(美)JohnF.Wakerly编
《FPGA应用开发入门与典型实例》华清远见嵌入式培训中心编
附件:
(源程序)
1.TOP文件:
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
entitytopis
Port(S_S:
inSTD_LOGIC;
S_R:
inSTD_LOGIC;
clk:
inSTD_LOGIC;
Out8:
outSTD_LOGIC_VECTOR(7downto0);
Seg:
outSTD_LOGIC_VECTOR(6downto0)
);
endtop;
architectureBehavioraloftopis
COMPONENTfenpingqi_48m_1k
PORT(
clk:
INstd_logic;
q:
OUTstd_logic
);
ENDCOMPONENT;
COMPONENTcounter
PORT(
clk:
INstd_logic;
eng:
INstd_logic;
clear:
INstd_logic;
ou:
OUTstd_logic;
daout1:
OUTstd_logic_vector(3downto0);
daout2:
OUTstd_logic_vector(3downto0);
daout3:
OUTstd_logic_vector(3downto0);
daout4:
OUTstd_logic_vector(2downto0);
daout5:
OUTstd_logic_vector(3downto0);
daout6:
OUTstd_logic_vector(2downto0));
ENDCOMPONENT;
COMPONENTkeydb
PORT(
clk:
INstd_logic;
key_in:
INstd_logic;
key_out:
OUTstd_logic
);
ENDCOMPONENT;
COMPONENTcontrol
PORT(
clk:
INstd_logic;
q:
INstd_logic;
p:
INstd_logic;
j_clr:
OUTstd_logic;
j_en:
OUTstd_logic;
s_en:
OUTstd_logic
);
ENDCOMPONENT;
COMPONENTlatch
PORT(
cnt_0:
INstd_logic_vector(3downto0);
cnt_00:
INstd_logic_vector(3downto0);
cnt_1:
INstd_logic_vector(3downto0);
cnt_11:
INstd_logic_vector(2downto0);
cnt_2:
INstd_logic_vector(3downto0);
cnt_22:
INstd_logic_vector(2downto0);
display_in:
INstd_logic;
cnt0:
OUTstd_logic_vector(3downto0);
cnt00:
OUTstd_logic_vector(3downto0);
cnt1:
OUTstd_logic_vector(3downto0);
cnt11:
OUTstd_logic_vector(2downto0);
cnt2:
OUTstd_logic_vector(3downto0);
cnt22:
OUTstd_logic_vector(2downto0)
);
ENDCOMPONENT;
COMPONENTdisplay
PORT(
clk_1k:
INstd_logic;
cnt0:
INstd_logic_vector(3downto0);
cnt00:
INstd_logic_vector(3downto0);
cnt1:
INstd_logic_vector(3downto0);
cnt11:
INstd_logic_vector(2downto0);
cnt2:
INstd_logic_vector(3downto0);
cnt22:
INstd_logic_vector(2downto0);
output:
outSTD_LOGIC_VECTOR(7downto0);
seg:
OUTstd_logic_vector(7downto1)
);
ENDCOMPONENT;
signalclk_1k,clk_100:
std_logic;
signalS_S_out,S_R_out:
std_logic;
signalclr_A,ena_A,lock_A:
std_logic;
signalco_out1,co_out2,co_out3,co_out4,co_out5:
std_logic;
signaldao1,dao2,dao3,dao5,daoA,daoB,daoC,daoE:
std_logic_vector(3downto0);
signaldao4,dao6,daoD,daoF:
std_logic_vector(2downto0);
signalDig:
std_logic_vector(2downto0);
begin
Inst_fenpingqi_48000:
fenpingqi_48m_1kPORTMAP(
clk=>clk,
q=>clk_1k
);
Inst_counter:
counterPORTMAP(
clk=>clk_1k,
eng=>ena_A,
clear=>clr_A,
daout1=>dao1,
daout2=>dao2,
daout3=>dao3,
daout4=>dao4,
daout5=>dao5,