电子科技大学FPGA实验秒表报告.docx
《电子科技大学FPGA实验秒表报告.docx》由会员分享,可在线阅读,更多相关《电子科技大学FPGA实验秒表报告.docx(40页珍藏版)》请在冰豆网上搜索。
电子科技大学FPGA实验秒表报告
电子科技大学FPGA实验秒表报告
电子科技大学
《现代电子技术综合实验报告》
姓名:
#*
学号:
**********
学院:
电子工程学院
指导老师:
皇晓辉
第一章引言
本文主要任务是针对设计的要求,基于FPGA利用硬件描述语言VHDL完成数字秒表的设计,通过仿真,分析,综合并最终下载到FPGA里实现。
本次实验是我们第一次接触VHDL语言。
设计秒表的过程并不难,通过本次实验让我们对FPGA有了一定的概念,掌握了部分VHDL语言的编写和仿真的步骤。
整个过程我们不仅学会了程序的编写,同时还清楚了怎样设计一个高效的电路,这在数字电路的学习上让我们提升了一个高度。
这次实验对今后电路的设计和VHDL的学习是一个良好的开端。
第二章设计背景
2.1FPGA的概念
FPGA,即现场可编程门阵列,它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。
它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。
以硬件描述语言(Verilog或VHDL)所完成的电路设计,可以经过简单的综合与布局,快速的烧录至FPGA上进行测试,是现代IC设计验证的技术主流。
这些可编辑元件可以被用来实现一些基本的逻辑门电路或者更复杂一些的组合功能比如解码器或数学方程式。
在大多数的FPGA里面,这些可编辑的元件里也包含记忆元件例如触发器或者其他更加完整的记忆块。
FPGA采用了逻辑单元阵列LCA这样一个概念,内部包括可配置逻辑模块CLB、输出输入模块IOB和内部连线三个部分。
FPGA是可编程器件,与传统逻辑电路和门阵列(如PAL,GAL及CPLD器件)相比,FPGA具有不同的结构。
FPGA利用小型查找表(16×1RAM)来实现组合逻辑,每个查找表连接到一个D触发器的输入端,触发器再来驱动其他逻辑电路或驱动I/O,由此构成了既可实现组合逻辑功能又可实现时序逻辑功能的基本逻辑单元模块,这些模块间利用金属连线互相连接或连接到I/O模块。
FPGA的逻辑是通过向内部静态存储单元加载编程数据来实现的,存储在存储器单元中的值决定了逻辑单元的逻辑功能以及各模块之间或模块与I/O间的联接方式,并最终决定了FPGA所能实现的功能,FPGA允许无限次的编程。
2.2FPGA设计流程
对于目标器件为FPGA和CPLD的HDL设计,其工程设计的基本流程如图2-1所示。
现具体说明如下
图2-1EDA设计流程
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程序设计上不是十分规范,语义上含有一定歧义的程序。
2.3VHDL语言简介
VHDL全名Very-High-SpeedIntegratedCircuitHardwareDescriptionLanguage,诞生于1982年。
VHDL翻译成中文就是超高速集成电路硬件描述语言。
VHDL主要用于描述数字系统的结构,行为,功能和接口。
除了含有许多具有硬件特征的语句外,VHDL的语言形式、描述风格以及语法是十分类似于一般的计算机高级语言。
VHDL的程序结构特点是将一项工程设计,或称设计实体(可以是一个元件,一个电路模块或一个系统)分成外部和内部,即设计实体的内部功能和算法完成部分。
在对一个设计实体定义了外部界面后,一旦其内部开发完成后,其他的设计就可以直接调用这个实体。
这种将设计实体分成内外部分的概念是VHDL系统设计的基本点。
现在,VHDL和VERILOG作为IEEE的工业标准硬件描述语言,又得到众多EDA公司的支持,在电子工程领域,已成为事实上的通用硬件描述语言。
2.4VHDL语言的优势
严格地讲,VHDL是一种用来描述数字逻辑系统的“编程语言”。
它通过对硬件行为的直接描述来实现对硬件的物理实现,代表了当今硬件设计的发展方向。
VHDL是为了满足逻辑设计过程中的各种需求而设计的。
第一,它是可以用来描述逻辑设计的结构,比如逻辑设计中有多少个子逻辑,而这些子逻辑又是如何连接的。
除此之外,VHDL并不十分关心一个具体逻辑依靠何种方式实现,而是把开发者的精力集中到逻辑所实现的功能上。
第二,VHDL采用类似高级语言的语句格式完成对硬件行为的描述,具备更强的模块化能力,并拥有良好的可读性以及程序的移植性。
另外,VHDL淡化状态机,与或表达式等早一代硬件描述语言中的元素,用更类似于高级语言的表达式取代。
这些也是为什么把VHDL称为“编程语言”的原因。
第三,VHDL给出逻辑的模拟与调试为设计工作提供了最大的空间。
VHDL调试的过程是相当灵活的:
一方面可以使用传统的调试方法,比如适用传统的波形激励或编写测试向量;另一方面,可以使用一些VHDL原码调试器,这类调试器可以大大加快VHDL程序调试的速度,因为它可以像调试软件一样单步跟踪调试每一条语句,并且可以设置断点,观察内部变量等。
这些功能是传统的调试仿真方法所不具备的。
这种调试器比较着名的有Aldec的Active-HDL。
拥有高效率的生成代码,能够节省大量的资源。
甚至不必编写任何测试向量便可以进行源代码级的调试。
而且,设计者可以非常方便地比较各种方案之间的可行性及其优劣而不需做任何实际的电路实验。
VHDL语言在编程时要更加规范,程序结构要适合整个系统的硬件结构,要符合各模块的信号时序关系,以及数据流的走向。
VHDL语言的设计格式更是面向具体的硬件对象的语言。
VHDL的语言特点主要有:
(1)更加类似软件上的高级语言,具备更强的模块化能力并拥有良好的可读性以及程序的移植性;
(2)淡化状态机,与或表达式等早一代硬件描述语言中的元素,用更类似于高级语言的表达式取代;
(3)拥有高效率的生成代码,能够节省大量的资源。
第三章程序设计
3.1各模块设计思路
3.1.1
秒表设计原理图
3.1.2
3.1.2.1按键消抖
按键消抖电路应用计数器的分频功能以及与门电路,将按下瞬间激起的高电平延迟一个周期以致抵消,从而达到消抖的作用。
当按键产生抖动时,keyin产生高电平,为了使keyout为低电平,将keyin与一个与门相连,使与门的另一端在抖动产生的一个周期内输入为0,所以在这个周期内,与门的输出恒为0,并将输出端接入keyout,从而实现消抖的功能。
ifrising_edge(clk_1k)then
ifcnt_2=3then
k3<='1';
else
k3<='0';
cnt_2<=cnt_2+1;
endif;
该局是利用计数器的分频功能;
key_out2<=notk3andk4;
该局是利用与门的功能;从而实现消抖的。
通过计数器与状态寄存,使得按下key1(start_stop)、key2(split_reset),这两个按键时,产生一个脉冲信号,实现了两个功能键的控制功能(源程序见附录1)。
3.1.2.2状态控制器
状态控制器
首先通过一个2位的向量定义了4个状态:
正常、暂停、清零、锁存即(normal、halt、reset、lock),以及按下两个按键以后,每个状态的转换,状态机有三个输出,根据状态器的变化与变化,三个输出分别是计数使能carry_in,清零使能rst,锁存使能latch。
其分别接到计数器的第一位的进位输入,计数器的清零端,以及锁存器的使能端,以达到控制计数器与锁存器,功能的目的。
(源程序见附录1)
2.扫描控制及显示译码的电路框图
因为实验板上的显示电路为下图
因为其只应用了一根总线,大大节省了I/O口的数量,从而大大减少了制作成本,所以其显示译码的电路图应该如下
当有时钟作用于扫描模块时,不断对8个数码管进行扫描,例如,q2q1q0为001时,把c1的数据赋给bcd2led进行显示。
3.1.2.3时钟分频器
时钟分频器应用计数器的模数的不同对晶振源进行分频,例如将48mhz分为1000hz,选用一个48000模的计数器对其进行分频,并应用480000模的计数器将48mhz分为100hz。
FPGA自带的时钟为48MHZ晶振源,但是秒表的基准时钟应该是100HZ的时钟,并且为了使得8位的数码管能够连续显示,我们也需要另一个1KHZ的时钟,对位选信号进行扫频以实现连续显示,因此分频器使非常关键的。
对输入的48MHZ进行一下操作:
要实现N分频,则输入源时钟信号clk每经过N/2个上升沿,则对输出信号去反。
(分频器源文件见附录1)。
3.1.2.4计数器
秒表一共需要六个计数器,2个模6的计数器,4个模10的计数器,通过if语句先判断是否有进位输入,当时钟上升沿到来时计数一次,再通过if语句判断计数是否到1001(模六计数器为0101),计数记到1001时则自动归零,另外还有对清零位的判断,若清零位有效则计数器始终保持为0。
各个计数器之间,通过将低位的进位输出赋值给高位的进位输入,从而达到计数器之间的级联,10毫秒位的计数器每当100HZ时钟上升沿到来时计一次数,从而实现了秒表的整体计数功能。
(源程序见附录1)
3.1.2.5锁存器
锁存器分为透明锁存器和不透明锁存器,本设计中,我们应用的是透明选择器,如下图,即当使能端en有效时,锁存器为“通”,即直接将计数器输入的数据传输出去,当时能端en无效时,锁存器进入锁存功能,此时停止计数,并将当前状态输出。
(源程序见附录1)
3.1.3.6显示模块
a.位选扫描
当1KHZ的时钟上升沿到来时,位选计数器加一,从而实现循环显示,由于扫描速度很快,人眼无法分辨,从视觉上秒表实际是连续显示。
程序如下:
process(clk_1khz)
begin
ifrising_edge(clk_1khz)then
s<=s+1;
endif;
endprocess;
choose<=s;
b.数码管译码
将每一位的BCD码输出接到译码器上,使其能让七段数码管能显示对应的十进制下的数字,从而实现的译码器的显示。
(源程序见附录1)
第四章仿真
4.1仿真软件使用说明
4.1.1ModelSim介绍
ModelSim支持PC和UNIX平台,是单一内核支持VHDL和Verilog混合仿真的HDL语言仿真器。
ModelSim不仅可以完成设计的功能验证,也可实现逻辑综合后的门级仿真以及布局布线后的功能与时序验证。
ModelSim完全支持VHDL和Verilog标准;采用直接编辑技术,大大提高HDL编译和仿真速度。
还可以利用ModelSim调用设计文件进行仿真分析。
在调试环境中,设计者可以通过ModelSim的快速调试步骤以及对各种信号的监控功能(无论信号处于VHDL层,还是处于混合语言层)使仿真的执行过程形象直观化,帮助设计者及时发现漏洞,缩短设计周期。
ModelSim最大的特点是其强大的调试功能:
先进的数据流窗口,可以迅速追踪到生产不定或者错误状态的原因;性能分析工具帮助分析性能瓶颈,加速仿真;代码覆盖率检查确保测试的完备;多种模式的波形比较功能;先进的SignalSpy功能,可以方便地访问VHDL或者VHDL和Verilog混合设计中的底层信号;支持加密IP;可以实现与Matlab的Simulink的联合仿真。
4.1.2ISE环境中ModelSim的使用
ModelSim是一个独立的仿真工具,它在工作的时候并不需要其他软件的协助,在Xilinx公司的ISE集成开发环境中给ModelSim仿真软件预留了接口,通过这个接口可以从ISE集成环境中直接启动ModelSim工具进行仿真。
这个过程通常会给初学者一个错觉,以为ISE集成环境和ModelSim工具是联合工作的,其实ISE并没有集成ModelSim工具,只是预留了软件接口。
为了说明ModelSim的用户接口,将使用从ISE集成开发环境中直接启动ModelSim仿真工具的方法。
使用此种方法启动ModelSim工具需要具备3个条件:
第一,启动ISE集成开发环境并建立了一个FPGA/CPLD的工程项目;第二,添加设计源代码并且编译通过;第三,使用ISE中的TestFixture或者TestBenchWaveform工具为当前的设计提供一个测试模板(Testbench),并且在测试模板中添加设计激励。
只有上述条件具备之后才可以从ISE的当前资源操作窗中直接启动ModelSim工具并运行仿真,以下使用ISE自带的一个例子加以说明。
在ISE中直接启动ModelSim
1、在Windows操作系统中选择[开始]/[程序]/[XilinxISE10.1]/[ProjectNavigator]命令,启动ISE集成开发环境。
2、在ISE主窗口中选择[File]/[OpenExample]命令,弹出[OpenExample]对话框,如图所示,然后在[SelectanExampleProject]栏目中选择“goldcode-ver-217”,在[DestinationDirectory]中选择项目存放的目录,单击OK按钮打开例子程序。
3、在资源管理窗口(SourceinProject)中的模块视图(ModelView)中选中的测试文件“testbench.tf”,在相应的当前资源操作窗口(ProcessforCurrentSource)中将会出现与Modelsim仿真器相关的行为仿真(SimulateBehavioralVerilogModel),翻译后仿真(SimulatePost-MapVerilogModel)和布局布线后仿真(SimulatePost-Place&RouteVerilogModel)等4个不同的操作选项,如图所示:
4、双击[SimulateBehavioralModel]操作选项,将启动Modelsim仿真器。
5、在Modelsim主窗口中选择[View]/[All]命令,将显示所有的窗口。
在当前资源操作窗口中选择任意一个操作选项都可以启动相应阶段的仿真操作,如果相应阶段的仿真文件不存在,那么集成环境将自动生成仿真文件。
4.2状态仿真图
A.计数器
模6计数器:
模10计数器:
B.分频器.
C锁存器
D消抖
E控制
F显示
致谢
此次实验,从一开始什么都不懂到最后自己完成设计,要多多感谢刘老师的细心讲解。
刘老师从最基本的数电知识的复习到VHDL语言的渗透,对我完成本次设计的完成功不可没。
这对我以后学习电路设计和语言编程增添了很多信心,
附录1:
1、顶层源文件
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entitytopis
Port(clk_top:
inSTD_LOGIC;
key1:
inSTD_LOGIC;
key2:
inSTD_LOGIC;
ncso:
outSTD_LOGIC;
displayo:
outSTD_LOGIC_VECTOR(6downto0);
chooseo:
outSTD_LOGIC_VECTOR(2downto0));
endtop;
architectureBehavioraloftopis
signala:
std_logic;
signalb:
std_logic;
signalr:
std_logic;
signalc:
std_logic;
signalc12:
std_logic;
signalc23:
std_logic;
signalc34:
std_logic;
signalc45:
std_logic;
signalc56:
std_logic;
signalla:
std_logic;
signalone:
std_logic;
signaltwo:
std_logic;
signalfour:
std_logic_vector(3downto0);
signalsix:
std_logic_vector(3downto0);
signalw:
std_logic_vector(3downto0);
signale:
std_logic_vector(3downto0);
signaln:
std_logic_vector(3downto0);
signali:
std_logic_vector(3downto0);
signalresult1:
std_logic_vector(3downto0);
signalresult2:
std_logic_vector(3downto0);
signalresult3:
std_logic_vector(3downto0);
signalresult4:
std_logic_vector(3downto0);
signalresult5:
std_logic_vector(3downto0);
signalresult6:
std_logic_vector(3downto0);
COMPONENTcontrol
PORT(
clk1000Hz:
INstd_logic;
start_stop:
INstd_logic;
split_reset:
INstd_logic;
rst:
OUTstd_logic;
carry_in:
OUTstd_logic;
latch:
OUTstd_logic
);
ENDCOMPONENT;
COMPONENTcount6
PORT(
clk:
INstd_logic;
rst:
INstd_logic;
carry_in:
INstd_logic;
carry_out:
outstd_logic;
count:
OUTstd_logic_vector(3downto0)
);
ENDCOMPONENT;
COMPONENTcount
PORT(
clk:
INstd_logic;
rst:
INstd_logic;
carry_in:
INstd_logic;
carry_out:
outstd_logic;
count:
OUTstd_logic_vector(3downto0)
);
ENDCOMPONENT;
COMPONENTdisplay
PORT(
clk1000hz:
INstd_logic;
d1:
INstd_logic_vector(3downto0);
d2:
INstd_logic_vector(3downto0);
d3:
INstd_logic_vector(3downto0);
d4:
INstd_logic_vector(3downto0);
d5:
INstd_logic_vector(3downto0);
d6:
INstd_logic_vector(3downto0);
choose:
OUTstd_logic_vector(2downto0);
ncs:
OUTstd_logic;
display7:
OUTstd_logic_vector(6downto0)
);
ENDCOMPONENT;
COMPONENTf_div
PORT(
clk:
INstd_logic;
clk100hz:
OUTstd_logic;
clk1000hz:
OUTstd_logic
);
ENDCOMPONENT;
COMPONENTsuocun
PORT(
latch:
INstd_logic;
count1:
INstd_logic_vector(3downto0);
count2:
INstd_logic_vector(3downto0);
count3:
INstd_logic_vector(3downto0);
count4:
INstd_logic_vector(3downto0);
count5:
INstd_logic_vector(3downto0);
count6:
INstd_logic_vector(3downto0);
d1:
OUTstd_logic_vector(3downto0);
d2:
OUTstd_logic_vector(3downto0);
d3:
OUTstd_logic_vector(3downto0);
d4:
OUTstd_logic_vector(3downto0);
d5:
OUTstd_logic_vector(3downto0);
d6:
OUTstd_logic_vector(3downto0)
);
ENDCOMPONENT;
COMPONENTxiaodou
PORT(