verilog感觉掌握的还不错了。最近准备学习一下VHDL。
了解了一下,VHDL的一个重要特征是具有描述大量同时发生的时间的能力。大量时间同时发生是数字系统工作时所具有的内在特征,这些时间被称为并行事件。
VHDL 的注释以两个连字符“--”开始,到该行尾自动结束,不支持成块的注释语句。
VHDL设计实体的组成:库和程序包(Library,Package),实体(Entity),结构体(Architecture),配置(Configuration).
--- VHDL Example
library ieee;
use ieee.std_logic_1164.all; --库声明
entity TONE is
port(A,B:in std_logic; --实体定义
Cut std_logic);
end TONE;
architecture EX of TONE is --结构体定义
begin
C<=A OR B;
end EX;
VHDL不区分大小写
1:实体的语句格式
ENTITY 实体名 IS
GENERIC(------);
--可选
PORT(------);
END 实体名;
类属说明的书写格式是:
GENERIC(常数名:数据类型:设定值;
常数名:数据类型:设定值);
端口语句的格式:
PORT(端口信号名:端口模式数据类型;
端口信号名:端口模式数据类型);
IN
输入
OUT
输出
INOUT
双向
BUFFER
缓冲
2.结构体
结构体的任务是:定义结构体中的各项内部使用元素,如数据类型(TYPE),常数(CONSTAND),信号(SIGNAL),元件(COMPONENT),过程(POCEDURE),变量(VARIABLE)和进程(PROCESS)等。通过VHDL语句描述实体所要求的具体行为和逻辑功能。描述各元件之间的连接。
结构体格式:
结构体名
OF 实体名 IS
说明部分 (可选,课用于对结构体中使用的信号等进行说明,这样做有利于提高程序的可读性)
BEGIN
功能描述语句法
END
结构体名称
VHDL内部是并发执行的,但是process内部的代码是顺序执行的。要实现时序电路,必须使用顺序执行代码。顺序执行代码可以同时实现组合逻辑电路和时序逻辑电路。
从本质上讲,VHDL 代码是并发执行的。只有PROCESS,FUNCTION或者PROCEDURE内部的代码才是顺序执行的。值得注意的是,尽管这些模块中的代码是顺序执行的,但是当它们作为一个整体是,与其他模块之间又是并发的。IF ,WAIT,CASE,LOOP语句都是顺序代码,用在PROCESS,FUNCTION和PROCEDURE内部。
我们将一系列的并发描述语句放在一个simple block中,目的仅仅是为了增强整个代码的可读性和可维护性。但是, 一个特殊的例子是利用guarded BLOCK可以构造时序电路。
类属
GENERIC
参量是一种端口界面常数,常以一种说明的形式放在实体或块结构体前的说明部分。
类属参量以关键词
GENERIC
引导一个类属参量表,在表中提供时间参数或总线宽度等静态信息。
一般在结构体中,类属的应用与常数是一样的,例如:当用实体例化一个设计实体的器件时,可以用类属表中的参数项定制这个器件,如可以将一个实体的传输延迟,上升和下降延时等参数加到类属参数表中,然后根据这些参数进行定制,这对于系统仿真控制是十分方便的。其中的常数名是由设计者确定的类属常数名,数据类型通常取
INTEGER
或TIME
等类型,设定值即为常数名所代表的数值,但需注意VHDL
综合器仅支持数据类型为整数的类属值。
GENERIC详细描述见以下网址
http://hi.baidu.com/rebornlinlin/item/0caedc0f8b0a058e03ce1b5a
一个元件 component 是一个结构完整的常用代码,(包括库声明、实体和结构体这些基本的组成部分)。然而如果将这些代码声明为component,就可以被其他电路调用,从而使代码具有了层次化的结构。
COMPONENT是已有元件在别的文件中已经定义,在此声明之后,你的程序里就可以用了就比如我在设计文件中定义了一个实体entity cnt6 is port (clr,en,clk :in std_logic; q ut std_logic_vector(2 downto 0) ); end entity;然后我要在测试文件中使用它,需要例化它,但首先要使用component对它进行声明。architecture rtl of cnt6_tb is component cnt6
port(
clr,en,clk :in std_logic;
q ut std_logic_vector(2 downto 0)
); end component; 关于VHDL 的testbench 的编写,请参照以下网址,写的蛮好http://blog.csdn.net/wangjun403/article/details/6246830http://www.cnblogs.com/zlh840/archive/2011/07/08/2101504.html
ƒCOMPONENT语句
COMPONENT
元件名
【GENERIC
说明】;
PORT
说明;
END COMPONENT;
COMPONENT语句可以在
ARCHITECTURE,PACKAGE及BLOCK
的说明部分中使用
ƒCOMPONENT_INSTANT语句
标号名:元件名
PORT MAP(信号,•••)
该语句使得使用已有元件或模块成为
可能,该语句将元件或模块的端口信号
映射成为高层次电路中的信号。
ƒCOMPONENT_INSTANT语句
标号名:元件名
PORT MAP(信号,•••)
该语句使得使用已有元件或模块成为
可能,该语句将元件或模块的端口信号
映射成为高层次电路中的信号。
例:已有设计and2的端口说明如下
Port(a,b:in bit;
cut bit);
元件调用
u1:and2 port map(x,y,q);
u2: and2 port map(a=>x,b=>y,c=>q);
在输出信号没有连接的情况下,其对应
端口的描述可以忽略
程序包说明格式如下:
package
程序包名
is
说明语句;
end
程序包名;
程序包名:设计者自定义便于记忆的标识符
说明语句:包括各种类型的说明语句
程序包体
描述函数和过程功能的函数体与过程等的集合称程序包体
程序包说明中,定义了数据类型和子程序中的函数、过程说明,而程序包体中才具体地描述该函数、过程功能的语句和数据的赋值。
程序包体格式:
package body
程序包名
is
顺序语句;
end
程序包名;
程序包名:与程序包说明中的程序包名相同
顺序语句:描述函数、过程及其他功能的程序流
子程序——过程
VHDL中,所谓子程序指主程序调用它后能将处理结果返回主程序的程序模块。
VHDL语言中,子程序有两种类型,过程(procedure)和函数(function)。
他们的区别:
1、过程可具有多个返回值,而函数只能有一个
2、过程通常用来定义一个算法,而函数往往用来产生一个特定的值
3、过程中的参数可具有3种端口模式:in、out、inout,而函数中的参数只能具有一直端口模式:in
过程的书写结构
对于VHDL子程序来说,它通常包括子程序说明部分和子程序定义部分。
其中,子程序说明部分定义了其他设计调用子程序的接口;子程序定义部分则描述该子程序具体功能的实现。
因此,通常将子程序说明部分和子程序定义部分的书写结构分别介绍
在VHDL中,过程说明部分的书写结构:
procedure:过程名
(对象类型1
参数名1: 端口模式1
数据类型1;
对象类型2
参数名2: 端口模式2
数据类型2;......);
其中对象类型、端口模式是可选项。
在VHDL语言中,过程定义部分
procedure
过程名
(对象类型1
参数名1: 端口模式1
数据类型1;
对象类型2
参数名2: 端口模式2
数据类型2;......)is
过程说明部分;
begin
过程顺序语句部分;
end
过程名;
参数列表中:每个参数包括它的对象类型、参数名、端口模式以及数据类型
参数的对象类型包括:常量、信号、变量
参数名是用来表示参数的唯一标识
端口模式:包括in、out、inout
若过程中没有指明参数的对象类型,那么参数的对象类型将默认为一个变量
过程定义在程序包中的定义规则为:过程说明部分书写在程序包的说明部分,过程定义部分书写在程序包体部分
过程定义在结构体中:即将过程定义部分书写在结构体的说明部分,然后在结构体进程语句里调用
函数
函数包括:函数说明部分和函数定义部分
函数说明部分定义了主程序调用函数的接口
函数定义部分描述了该函数具体逻辑功能的实现
函数的书写结构
function
函数名
(对象类型1
参数名1;
in
数据类型1;
对象类型2
参数名2;
in
数据类型2;......)
return
数据类型;
其中对象类型和端口模式in是可选项
函数定义部分书写结构
function
函数名
(对象类型1
参数名1;
in
数据类型1;
对象类型2
参数名2;
in
数据类型2;......)
return
数据类型
is
函数说明部分:
begin
函数顺序语句部分;
return(参数值);
end
函数名;
函数参数的对象类型只能包括常量和信号:参数的端口模式只能是in,因此参数端口模式可以省略。
函数的返回值只能有一个。
函数定义在程序包中:函数说明部分书写在程序包说明部分,函数定义部分书写在程序包体部分。如果需要使用程序包中定义的函数,那么只需要通过use语句使其对设计实体可见。
函数定义在结构体中:只需将函数定义部分书写在结构体说明部分即可。然后在结构体中调用这个函数。
function内是不允许加入进程process的。函数function的通常应用是作逻辑组合、判决和转移。
Function 例子
function max(a,b:bit)
return boolean is variable :flag:boolean;
begin
if (a=b)then
flag<=true;
end if
return flag;
end max
Pprorocedure例子
procedure max(a,b:in bit;
flag:out boolean)is
begin
if (a=b)then
flag<=true;
end if
end max;
Vhdl 程序包
程序包是用VHDL语言编写的一段程序,可以供其他设计单元调用和共享,相当于公用的“工具箱”,各种数据类型、子程序等一旦放入了程序包,就成为共享的“工具”,类似于C语言的头文件,使用它可以减少代码的输入量,使程序结构清晰。在一个设计中,实体部分所定义的数据类型、常量和子程序可以在相应的结构体中使用,但在一个实体的声明部分和结构体部分中定义的数据类型、常量及子程序却不能被其他设计单元使用。因此,程序包的作用是可以使一组数据类型、常量和子程序能够被多个设计单元使用。
程序包分为包头和包体两部分。包头(也称程序包说明)是对包中使用的数据类型、元件、函数和子程序进行定义,其形式与实体定义类似。包体规定了程序包的实际功能,存放函数和过程的程序体,而且还允许建立内部的子程序、内部变量和数据类型。包头、包体均以关键字PACKAGE开头。程序包格式如下。
包头格式:
PACKAGE 程序包名 IS
[包头说明语句]
END 程序包名;
包体格式:
PACKAGE BODY 程序包名 IS
[包体说明语句]
END 程序包名;
调用程序包的通用模式为:USE 库名.程序包名.ALL;
|