上机实验VHDL程序设计Word文档格式.docx
《上机实验VHDL程序设计Word文档格式.docx》由会员分享,可在线阅读,更多相关《上机实验VHDL程序设计Word文档格式.docx(18页珍藏版)》请在冰点文库上搜索。
行为描述、数据流描述、结构化描述。
结构体的语法:
architecture结构体名称of实体名称is
[说明语句]内部信号、常数、
数据类型、子程序(函数、过程)、
元件等的说明;
begin
[并行处理(功能描述)语句];
end[architecture]结构体名称;
(3)程序包、库
程序包:
已定义的常数、数据类型、元件调用说明、子程序的一个集合。
目的:
方便公共信息、资源的访问和共享。
库:
多个程序包构成库。
(4)VHDL并发信号赋值语句
并发信号赋值语句就是应用于结构体中进程和子程序之外的一种基本信号赋值语句,它与信号赋值语句的语法结构是完全一样的。
作为一种并行描述语句,结构体中的多条并发信号赋值语句是并行执行的,它们的执行顺序是与书写顺序无关的。
(5)VHDL条件信号赋值语句
在VHDL中,条件信号赋值语句是指根据不同条件将不同的表达式赋给目标信号的一种并行信号赋值语句,它是一种应用较为广泛的信号赋值语句。
一般来说,条件信号赋值语句的语法结构如下所示:
目标信号<
=表达式1WHEN条件1ELSE
表达式2WHEN条件2ELSE
表达式3WHEN条件3ELSE
……
表达式n-1WHEN条件n-1ELSE表达式n;
程序执行到该语句时首先要进行条件判断,然后根据不同条件的判断情况来将不同的表达式赋给目标信号。
如果条件满足,那么就将条件前面的那个表达式的值赋给目标信号;
如果条件不满足,那么就去判断下一个条件。
可以看出,语法结构中的最后一个表达式没有条件,它表示当前面的所有条件都不满足时,程序就将表达式n的值赋给目标信号。
使用条件信号赋值语句需要注意以下几个方面:
1)只有当条件满足时,语句才能将这个条件前面的表达式赋给目标信号。
2)语句是一种并行描述语句,它不能在进程和子程序中使用。
3)语句对条件进行判断是有顺序的,位于语句前面的条件具有较高的优先级0
4)语句中最后一个表达式的后面不含有WHEN子句。
5)语句中条件表达式的结果为boolean型数值,同时允许条件重叠。
6)条件信号赋值语句不能进行嵌套,因此它不能生成锁存器。
(6)VHDL选择信号赋值语句
在VHDL中,选择信号赋值语句是指根据选择条件表达式的值将不同的表达式赋给目标信号的一种并行信号赋值语句。
选择信号赋值语句的语法结构如下所示:
WITH选择条件表达式SELECT
目标信号。
表达式1WHEN选择条件1,
表达式2WHEN选择条件2,
表达式3WHEN选择条件3,
表达式nWHEN选择条件n;
程序执行到该语句时首先要进行选择条件表达式的判断,然后根据条件表达式的值来决定将哪一个表达式赋给目标信号。
如果选择条件表达式的值符合某一个选择条件,那么就将该选择条件前面的表达式赋给目标信号;
如果选择条件表达式的值不符合某一个选择条件,那么程序就去继续判断下一个选择条件,直到找到满足的选择条件为止。
在编写VHDL程序的过程中,使用选择信号赋值语句需要注意以下几个方面:
1)只有当条件表达式的值满足选择条件时,语句才能将前面的表达式赋给目标信号。
2)语句是一种并行描述语句,它不能在进程和子程序中使用。
3)语句中的表达式后面都含有WHEN子句。
4)语句对选择条件的测试是同时进行的,因此不允许选择条件重叠。
5)语句中的选择条件不允许出现涵盖不全的情况。
(7)VHDL顺序描述语句
并行描述语句是用于表示算法模块间的连接关系的语句,而顺序描述语句则是用于实现模块的算法部分的语句。
除了提供大量的并行描述语句外,VHDL还提供了很多顺序描述语句。
在VHDL中,顺序描述语句只能出现主进程、过程和函数中,功能是用来实现进程、过程和函数的具体算法或者控制程序流程。
顺序描述语句,顾名思义,是指语句的执行顺序是完全按照书写顺序来进行的,同时前面语句的执行结果会对后面语句的执行结果产生影响。
另外,许多参考文献将顺序描述语句按照控制方式分为条件控制语句和迭代控制语句,其中条件控制语句有IF语句和CASE语句,迭代控制语句有循环语句和顺序断言语句等.
(8)VHDL赋值语句
在编写VHDL程序的过程中,设计人员经常会采用两种类型的信号赋值语句:
一种是应用于进程和子程序内部的信号赋值语句,这时它是一种顺序语句,因此称为顺序信号赋值语句;
另外一种是应用于进程和子程序外部的信号赋值语句,这时它是一种并行语句,因此称为并行信号赋值语句。
(9)VHDLIF语句
提到IF语句,相信具有高级软件编程基础的读者对此一定不陌生。
与其他高级编程语言类似;
VHDL中的IF语句也是一种具有条件控制功能的语句,它同样是根据给出的条件来决定需要执行程序中的哪些语句,在VHDL中,IF语句具有3种形式,下面对它们进行分别介绍。
(1)具有开关控制的IF语句
主VHDL中,具有开关控制的IF语句是一种非常基本的顺序描述语句。
通常,它的语法结构如下所示:
If<
条件>
THEN
<
顺序处理语句>
;
ENDIF;
当程序执行到IF语句时,如果IF语句中的条件成立,那么程序将执行后面的顺序处理语句;
否则程序将跳出IF语句,转而去执行其他的程序处理语句。
真有开关控制的IF语句的典型应用是用来描述数字电路中的基本D触发器,它的处理程序如下所示。
LIBRARYieee;
USEieee.std_logic_1164.all;
ENTITYdff1IS
PORT(
D,clk:
INSTD_LOGIC;
Q:
outSTD_LOGIC
);
ENDdff1;
ARCHITECTUREa1OFdff1IS
BEGIN
process(clk)
begin
ifclk'
eventandclk='
1'
then
Q<
=D;
endif;
endprocess;
ENDa1;
(2)具有二选择控制的IF语句
在VHDL中,具有二选择控制的IF语句经常用来描述具有两个分支控制的逻辑功能电路。
顺序处理语句1>
ELSE
顺序处理语句2>
当程序执行到IF语句时,如果IF语句中的条件成立,那么程序将会执行后面的顺序处理语句1;
否则程序将会去执行顺序处理语句2。
(3)具有多选择控制的IF语句
在VHDL中,具有多选择控制的IF语句经常用来描述具有多个选择分支的逻辑功能电路。
通常,它的语法结构如下所示:
IF<
条件1>
〈顺序处理语句1>
ELSIF<
条件2>
条件n-I>
顺序处理语句n-I>
顺序处理语句n>
ENDIF:
当程序执行到IF语句时,如果IF语句中的条件1成立,那么程序将会执行后面的顺序处理语句1;
如果IF语句中的条件2成立,那么程序将会执行后面的顺序处理语句2;
依此类推,如果IF语句中的条件n-1成立,那么程序将会执行后面的顺序处理语句n-1;
如果IF语句中的前n-1个条件均不成立,那么程序将会去执行顺序处理语句no
(4)IF语句的嵌套
IF语句也可以进行多层嵌套。
在编写VHDL程序的过程中,IF语句的嵌套可以用来解决描述具有复杂控制功能的逻辑电路的问题。
下面通过IF语句的嵌套来描一个具有同步置位功能的D触发器,它的VHDL程序如例4-26所示。
ENTITYdff2IS
D,clk,clr:
ENDdff2;
ARCHITECTUREa1OFdff2IS
process(clk,D,clr)
begin
ifclk'
ifclr='
Q<
='
else
endif;
endprocess;
(10)VHDLCASE语句
在VHDL中,CASE语句是另外一种形式的条件控制语句,它与IF语句一样可以用来描述具有控制功能的数字电路。
一般来说,CASE语句是根据表达式的值来从不同的顺序处理语句序列中选取其中的一组语句来进行操作,它常常用来描述总线、编码器、译码器或者数据选择器等数字逻辑电路的具体功能。
也许有人会问:
CASE语句的描述功能实际上采用IF语句也能够实现,那么VHDL为什么要提出一个新的CASE语句呢?
实际上,虽然CASE语句和IF语句都是通过条件的判断来决定需要执行程序中的哪些语句,但是由于CASE语句中条件表达式的值与所要执行的顺序处理语句的对应关系十分明显,因此CASE语句的可读性要比IF语句强得多。
一般来说,CASE语句的语法结构如下所示:
CASE<
条件表达式>
IS
WHEN<
条件表达式的取值1>
=>
<
条件表达式的取值2>
条件表达式的取值n-l>
=>
顺序处理语句n-l>
WHENOTHERS=>
ENDCASE;
当程序执行到CASE语句时,如果条件表达式的计算值与取值1相同,那么程序就去执行CASE语句中的顺序处理语句1;
如果条件表达式的计算值与取值2相同,那么程序就去执行CASE语句中的顺序处理语句2;
依此类推,如果条件表达式的计算值与取值n-l相同,那么程序就去执行CASE语句中的顺序处理语句n-1;
如果条件表达式的计算值与前面n-l个取值都不相同,那么程序就去执行CASE语句中的顺序处理语句n.
通常情况下,CASE语句中的WHEN子句具有5种不同的书写格式。
因此,在编写VHDL程序的过程中,设计人员可以根据设计的需要来选择采用哪一种书写格式。
在CASE语句与中,WHEN子句的5种书写格式如下所示:
1)WHEN取值=>
2)WHEN取值|取值|…|取值=>
3)WHEN取值TO取值=>
4)WHEN取值DOWNTO取值=>
5)WHENOTHERS=>
在编写VHDL程序的过程中,设计人员使用CASE语句时需要注意以下几个方面:
1)条件表达式的所有取值必须在WHEN子句中被列举出来。
2)WHEN子句中的取值必须在条件表达式的取值范围之内。
3)不同的WHEN子句中不允许出现相同条件表达式的取值0
4)WHEN子句中可以采用保留字OTHERS来表示所有具有相同操作的取值。
5)WHEN子句可以任意颠倒次序而不会影响描述的逻辑功能。
6)含有保留字OTHERS的WHEN子句必须放在CASE语句的最后面。
7)含有保留字OTHERS的WHEN子句在CASE语句中只能出现一次。
(11)VHDL信号
信号是指在设计实体之间动态交换数据的一种手段,采用信号对象可以把设计实体连接在一起形成模块。
在VHDL中,信号的应用十分广泛,它可以在程序的很多区域进行说明,并且可以具有任何数据类型的值。
同样,作为一种硬件描述语言中的对象,信号在硬件电路设计中具有一定的物理意义,它通常用来代表硬件电路中的一条硬件连接线。
在VHDL程序中,信号能够实现各个模块之间的通信,因此使用信号能够使设计人员容易地编写出模块化的VHDL程序,也因此能够实现VHDL所提倡的模块化设计思想。
例如,前面提到变量只能在其所定义的进程语句、过程语句以及函数语句中使用,而设计中常常需要在它们之间进行通信,这时候只能采用信号来完成。
在VHDL中,信号说明的语法结构为:
SIGNAL信号名[,信号名…]:
数据类型[:
=表达式];
下面是几个信号说明的小例子。
SIGNALclk:
bit:
='
0'
SIGNALreset:
SIGNALdata_bus:
bit_vector(7DOWNTO0):
="
00000000"
SIGNALaddrbus:
bit_vector(7DOWNTO0);
同样,在信号说明中,可以对它赋予初始值,也可以不赋初始值。
如果在信号说明中没有指定初始值,那么认为它取默认值,即该数据类型的最左值或者是最小值。
通常,如果信号说明中对信号赋了初始值,那么这个初始值对于仿真来说是有用的,但是它对于综合来说意义不大,其原因是信号说明中设定的初始值与实际器件加电时的初始状态并不一定能够保持一致。
至于实际器件加电时的初始状态,设计人员要参考与该器件有关的手册。
这里可以给出这样一个原则;
如果需要对VHDL程序进行仿真操作,那么可以给信号赋予初始值;
如果不需要对VHDL程序进行仿真操作,那么就不要给信号赋予初始值了,这样上电时器件会自动将上电初始值赋给该信号。
与变量一样,信号的值也是能够被改变的,它可以在VHDL程序中被连续地赋值。
VHDL中信号值的改变是通过信号赋值语句来完成的。
信号赋值语句的语法结构为:
=表达式;
不难看出,信号赋值语句使用的符号与信号初始化的符号是完全不同的:
前者采用符号"
:
="
来进行信号赋值操作;
而后者则采用符号"
="
来进行信号的初始化操作。
对于信号赋值语句来说,赋值符号两边的目标信号和表达式的数据类型和长度必须保持一致,否则编译将会出现错误。
四、实验步骤:
1.新建项目工程
(1)先建一个文件夹。
就在电脑本地硬盘找个地方建一个用于保存下一步工作中要产生的工程项目的文件夹,注意:
文件夹的命名及其保存的路径中不能有中文字符。
(2)再开始建立新项目工程,方法如右图点击:
【File】菜单,选择下拉列表中的【NewProjectWizard...】命令,打开建立新项目工程的向导对话框。
选择项目工程保存位置、定义项目工程名称以及设计文件顶层实体名称。
第二栏(项目工程名称)和第三栏(设计实体名称)软件会默认为与之前建立的文件夹名称一致。
没有特别需要,我们一般选择软件的默认,不必特意去修改。
需要注意的是:
以上名称的命名中不能出现中文字符,否则软件的后续工作会出错。
完成以上命名工作后,点击Next,进入下一步。
第2步的工作是让你将之前已经设计好的工程文件添加到本项目工程里来,若没有之前设计好的文件,直接点Next,再进入下一步。
第3步的工作是让你选择好设计文件下载所需要的可编程芯片的型号,本实验中可任选一种,比如CycloneⅢEP3C40Q240C8。
第4步是让你选择第三方开发工具,如不需要,直接点击Next,进入下一步。
2.新建设计文件
本实验采用VHDL编写源程序。
(1)创建VHDL文件
从File菜单中选择【New…】命令,打开新建设计文件对话框,如下图。
(2)编写VHDL程序
(3)保存VHDL文件
选择File—〉Save,要求文件与模块名称一致。
3.项目工程编译
设计好的程序若要让软件能认识并检查设计的电路是否有错误,需要进行项目工程编译,QuartusII软件能自动程序进行编译和检查设计的正确性。
方法如下:
在【Processing】菜单下,点击【StartCompilation】命令,或直接点击常用工具栏上的按钮,开始项目。
编译成功后,点击确定按钮。
4.功能仿真
仿真是指利用QuartusII软件对所设计电路的逻辑功能进行验证,在进行仿真之前,需要先建立一个输入信号波形文件。
方法和步骤如下:
(1)在【File】菜单下,点击【New】命令。
在随后弹出的对话框中,切换到【OtherFiles】页。
选中【VectorWaveformFile】选项,点击OK按钮。
(2)在【Edit】菜单下,点击【InsertNodeorBus…】命令,或在下图Name列表栏下方的空白处双击鼠标左键,打开编辑输入、输出引脚对话框。
(3)在上图新打开的对话框中点击【NodeFinder…】按钮,打开【NodeFinder】对话框。
点击【List】按钮,列出电路所有的端子。
点击>
>
按钮,全部加入。
点击OK按钮,确认。
点击OK回到InsertNodeorBus对话框,再点击OK按钮,确认。
(4)设置输出参数,可根据实际情况设置,例如:
选择Edit—〉Endtime1μs
选择View—〉FitInWindow
选择Edit—〉Gridsize—〉50ns
(5)为输入端口赋值。
(6)QuartusII软件集成了电路仿真模块,电路有两种模式:
时序仿真和功能仿真,时序仿真模式按芯片实际工作方式来模拟,考虑了元器件工作时的延时情况,而功能仿真只是对设计的电路其逻辑功能是否正确进行模拟仿真。
在验证所设计的电路是否正确时,常选择“功能仿真”模式。
将仿真模式设置为“功能仿真”模式,操作方法如下图所示:
(7)选择好“功能仿真”模式后,需要生成一个“功能仿真的网表文件”,方法是如下图,选择【Processing】菜单,点击【GenerateFunctionalSimulationNetlist】命令。
软件运行完成后,点击确定。
8)开始功能仿真,在【Processing】菜单下,选择【StartSimulation】启动仿真工具,或直接点击常用工具栏上的
按钮。
仿真结束后,点击确认按钮。
观察仿真结果,对比输入与输出之间的逻辑关系是否符合电路的逻辑功能。