1 VHDL语言的标识符
VHDL中的标识符可以是常数、变量、信号、端口、子程序或参数的名字。使用标识符要遵守如下法则:
a) 标识符由字母(A…Z;a…z)、数字和下划线字符组成。
任何标识符必须以英文字母开头。
末字符不能为下划线。
b) 不允许出现两个连续下划线。
标识符中不区分大小写字母。
VHDL定义的保留子或称关键字,不能用作标识符。
c) VHDL中的注释由两个连续的短线(--)开始,直到行尾。
以下是非法标识符:
-Decoder —起始不能为非英文字母
3DOP —起始不能为数字
Large#number —“#”不能成为标识符的构成符号
Data__bus —不能有双下划线
Copper_ —最后字符不能为下划线
On —关键字不能用作标识符。
注:在AHDL语言中标识符要区分大小写,但在VHDL语言中不区分大小写。所以写程序时,一定要养成良好的书写习惯,应用关键字时用大写,自己定义的标识符用小写。
标识符表示的几种数据对象的详细说明如下:
1) 常数(Constant )
常数是一个固定的值,主要是为了使设计实体中的常数更容易阅读和修改。常数一被赋值就不能在改变。一般格式:
CONSTANT 常数名:数据类型:=表达式;
例:CONSTANT Vcc: REAL: =5.0;
—设计实体的电源电压指定
常数所赋得值应与定义的数据类型一致。
常量的使用范围取决于它被定义的位置。程序包中定义的常量具有最大的全局化特性,可以用在调用此程序包的所有设计实体中;设计实体中某一结构体中定义的常量只能用于此结构体;结构体中某一单元定义的常量,如一个进程中,这个常量只能用在这一进程中。
2) 变量(Variable)
变量是一个局部变量,它只能在进程语句、函数语句和进程语句结构中使用。用作局部数据存储。在仿真过程中。它不像信号那样,到了规定的仿真时间才进行赋值,变量的赋值是立即生效的。变量常用在实现某种算法的赋值语句中。
一般格式:
VARIABLE 变量名 数据类型 约束条件:=表达式;
例:VARIABLE x,y:INTEGER; —定义x,y为整数变量
VARIABLE count: INTEGER RANGE0 TO255:=10; —定义计数变量范围
变量的适用范围仅限于定义了变量的进程或子程序中。若将变量用于进程之外,必须该值赋给一个相同的类型的信号,即进程之间传递数据靠的信号。
变量赋值语句的语法格式如下:
目标变量:=表达式;
变量赋值符号是“:=”。赋值语句右方的表达式必须是一个与目标变量有相同数据
类型的数值。变量不能用于硬件连线和存储元件。
3) 信号(Signal)
信号是描述硬件系统的基本数据对象,它类似于连接线,它除了没有数据流动方向说明以外,其它性质与实体的端口(Port)概念一致。变量的值可以传递给信号,而信号的值不能传递给变量。信号通常在构造体、包集合和实体中说明。信号说明格式为:
SIGNAL 信号名: 数据类型;
信号初始值的设置不是必需的,而且初始值仅在VHDL的行为仿真中有效。
1. 变量
变量只能在进程、函数和过程中使用,一旦赋值立即生效。
例:VARIABLE x, y: INTEGER;
VARIABLE count: INTEGER RANGE 0 TO 255:=10;
2. 信号
信号除了没有方向的概念以外几乎和端口概念一致。
例:SIGNAL sys_clk: BIT:=’0’;
SIGNAL ground: BIT:=’0’
在程序中,信号值输入信号时采用代入符”<=”,而不是赋值符“:=”,同时信号可以附加延时。
信号传送语句:
s1<=s2 AFTER 10ns
信号是一个全局量,可以用来进行进程之间的通信
3. 信号与变量的区别:
信号赋值可以有延迟时间,变量赋值无时间延迟;
信号除当前值外还有许多相关值,如历史信息等,变量只有当前值;
进程对信号敏感,对变量不敏感;
信号可以是多个进程的全局信号,但变量只在定义它之后的顺序域可见;
信号可以看作硬件的一根连线,但变量无此对应关系。
2 VHDL语言的数据类型 VHDL语言提供了许多标准的数据类型,用户也可自定义数据类型,这样使VHDL语
言的描述能力和自由度进一步提高。但VHDL语言的数据类型的定义相当严格,不同类型之间的数据不能直接代入。而且相同数据类型,但位长不同的也不能直接代入,否则EDA工具在编译综合时会报告类型错。因此,为了熟练地使用VHDL 语言编写程序,必须很好的理解各种数据意义。
2.1. VHDL标准的数据类型
1) 整数(Integer)
整数类型的数代表正整数、负整数和零,表示的范围-(231-1)~(231-1),它与算术整数相似,可进行“+”,“-”,“*”,“/”等算术运算,不能用于逻辑运算。
2) 实数(Real)
实数类型也类似于数学上的实数,或称浮点数,表示范围为-1.0E38~1.0E38.
3) 位(Bit)
在数字系统中信号通常采用一个位来表示,取值值能是1获0。
4) 位矢量(Bit_Vector)
位矢量是用双引号括起来的一组位数据,使用位矢量必须注明位宽。
例如:SIGNAL a:BIT_VEVCTOR(7to0)
信号a被定义为一个具有8位位宽的矢量,最左位为a(7),最右位为a(0)。
5) 布尔量(Boolean)
一个布尔量具有两个状态:“真”或“假”。布尔量不属于数值,因此不能用于运算,它只能通过关系运算符获得。一般这一类型的数据初始值总为FALSE.
6) 字符(Character)
字符也是一种数据类型,字符类型通常用单引号引起来,如‘A’。字符类型区分大小写,如‘B’不同于‘b’。
7) 字符串(String)
字符串是由双引号括起来的一个字符序列,也称字符矢量或字符串数组。常用于程序的提示和说明,如“STRING”等。
8) 时间(Time)
时间是一个物理数据。完整的时间类型包括整数和单位两部分;整数与单位之间至少留一个空格,如55 ms,2 ns。在包集合STANDARD中给除了时间的预定义,其单位为fs,ps,ns,us,ms,sec,min,hr。
在系统仿真时,时间数据很有用,可用它表示信号延时,从而使模型系统能更逼近实际系统的运行环境。
9) 错误等级(Severity Level)
在VHDL仿真器中,错误等级用来指示设计系统的工作状态,它有四种:NOTE(注意)、WARNING(警告)、 ERROR(出错)、 FAILURE(失败)。在仿真过程中,可输出这四种状态以提示系统当前的工作状态。
10) 自然数(Natural)和正整数(Positive)
自然数是整数的一个子类型,非负的整数,即为零和正整数。而Positive只能为正整数。
2.2. IEEE预定义标准逻辑位与矢量 在IEEE库的程序包STD_LOGIC11中,定义了两个重要的数据类型,即标准逻辑位STD_LOGIC和标准逻辑矢量STD_LOGIC_VECTOR,使得STD_LOGIC数据可以具有如下的9种不同的值:
“U”—初始值
“0”—0
“Z”—高阻
“L”—弱信号0
“X ”—不定
“1”—1
“W”—弱信号不定
“H”—弱信号1
“_”—不可能情况
注意在使用该类型数据时,在程序中必须写出库说明语句和使用包集合的说明语句。
3 VHDL语言的运算操作符
在VHDL语言用4类操作符,可以分别进行逻辑运算(Logic)、关系运算(Relational)、算术运算(Arithmetic)和并置运算(Concatenation)。被操作符所操作的对象是操作数,且操作数的类型应该和操作符所要求的类型相一致。需要注意的是,各家EDA综合软件对运算操作符支持程序各不相同,使用时应参考综合工具说明。
1) 逻辑运算符
运算符在VHDL语言中逻辑运算符有6种,他们分别为:
NOT(非)
OR(或)
AND(与)
NOR(或非)
NAND(与非)
XOR(异或)
2) 关系运算符
关系运算符它们分别是:
=(等于)
/=(不等于)
<(小于)
<=(小于等于)
>(大于)
>=(大于等于)
3) 算术运算符
+(加)
/(除)
SLL(逻辑左移)
ROR(逻辑循环右移)
-(减)
MOD(求模)
SRL(逻辑右移)
ABS(取绝对值)
*(乘)
REM(取余)
SLA(算术左移)
4) 其他运算符
<=(信号赋值)
:=(信号赋值)
-(负)
+ (正) & (并置运算符,用于位的连接)
=>(并联运算符,在元件例化时可用于形参倒实参的映射)
4 VHDL语言的结构 VHDL语言主要组成构件有设计实体(Entity)、结构体(Architecture)、子程序( Function Procedure )、集合包(Package)和库(Library),前四种称为可编译的设计单元。一个VHDL设计就是有这四种构件的组成,编译之后将它们放在制定的库享。其中,实体用于描述设计的接口界面信号,它规定端口数目,端口方向和端口类型。它与硬件电路设计中
的符号相对应。而结构体指定设计的真实行为,性能和结构,与硬件电路设计中的原理图相对应。子程序是可被调用的执行某一特定功能算法的集合。集合包则是为了使常用的数据类型、常数和子程序对于其他设计块可用而集中充放的一批设计单元和约定。
4.1 设计实体 实体的定义语法为:
ENTITY 实体名 IS
[端口说明];
END 实体名;
端口说明书写格式如下:
PORT(端口名{,端口名}:方向 数据类型名;
……
……
……
端口名{,端口名}:方向 数据类型名);
例如,一个二选一路数据选择器的设计实体可描述如下:
ENTITY selection IS
PORT(a, b, sel: IN BIT;
C : OUT BIT );
END selection;
4.2 构造体 用于描述系统内部的结构和行为。构造体部分定义了设计单元的具体功能(行为)。
1. 构造体句法如下:
ARCHITECTURE 构造体名 OF 实体名 IS
[定义语句]内部信号,常数,数据类型,函数等的定义;
BEGIN
[并行处理语句];
END 构造体名;
例如:ARCHITECTURE dataflow OF selection IS
BEGIN
q<=(a AND set) OR (NOT sel AND d1);
END dataflow;
4.2.1 构造体的子结构描述
在规模较大的电路设计中,全部电路都用唯一的一个模块来描述是非常不方便的。为此,电路设计者总希望将整个电路分成若干个相对比较大的模块来进行电路的描述。这样,
一个构造体可以用几个子结构,既相对比较的几个模块来构成。VHDL语言可以有以下三种形式的子结构描述语句:
1) 子程序:
VHDL提供两种子程序:函数(FUNCTION)和过程(PROCEDURE)
函数
函数的定义形式如下:
FUNCTION<函数名称><接口表>RETURN<数据类型>IS
[定义语句];
BEGIN
<函数语句部分>;
END 函数名称;
.下面是一个比较器的例子:FUNCTION max(a, b: INTEGER) RETURN INTEGER IS
BEGIN
IF (a>=b)THEN RETURN a;
ELSE RETURN b;
END IF;
END max;
一个函数定义好后,可以在其它地方调用。
过程
过程的定义形式如下:
PROCEDURE<过程名称><接口表> IS
BEGIN
<过程语句部分>;
END 过程名称;
.下面是一个比较器的例子:
FUNCTION max(a, b, c: INTEGER) IS
BEGIN
IF (a>=b)THEN c<= a;
ELSE c<=b;
END IF;
END max;
2) BLOCK语句
采用BLOCK语句描述局部电路的书写格式如下:
块结构名:
BLOCK
BEGIN
…
…
…
END BLOCK 块结构名;
3) 进程语句(PROCESS)
采用PROCESS语句描述局部电路的书写格式如下:
[进程名]:PROCESS:(信号1,信号2…)
BEGIN
…
…
…
END PROCESS
4.3 包集合、库及配置 除实体和构造体外,包集合、库及配置是VHDL语言和另外3个可以各自进行编译的源设计单元。
1. 库(LIBRARY)
一个库中可以包含包集合,公用的设计实体和公用的机构体等。当需要引用一个库时,首先需要对库名进行说明,其格式为:
LIBRARY 库名
这时就可以使用库中已经编译好的设计。对库中集合包的访问必须再经由USE语句才能打开。其格式为:
USE 程序包名
IEEE库是IEEE制定的一个VHDL的最常用标准库,其中包括标准逻辑程序包Sed_logic_11,标准数学程序包Math等。我们可以使用它的数据类型和函数。用法:LIBRARY IEEE。
STD库也是VHDL的标准库。
2. 包集合(Package)
包集合(Package)说明像C语言中的include语句一样,用来单纯的罗列VHDL语言中所要用到的信号定义、常数定义、数据类型、元件语句、函数定义和过程定义等。使用包集合时用USE语句说明。如USE IEEE.STD_logic_11.ALL;
3. 配置(Configuration)
配置语句描述层于层之间的连接关系以及实体与结构之间的连接关系。设计者可以利用这种配置语句来选择不同的构造体,使其与要设计的实体相对应。
配置语句的格式:
CONFIGURATION 配置名OF 实体名IS
[语句说明];
END 配置名;
5 VHDL常用顺序语句 VHDL语句是并发语言,大部分语句是并发执行的。但在进程、过程、块语句和子程序(包括函数)中,还有许多顺序执行语句,按出现的次序执行各条语句。下面以常用的两种语句为例,其他的语句请参考其他书。
1. IF语句
IF语句是根据所制定的条件来确定执行那些语句的,其格式由三种:
第一种
IF 条件 THEN 顺序语句
END IF
第二种
IF语句二选择控制,其书写格式为:
IF 条件 THEN
顺序处理语句;
ELSE
顺序处理语句;
END IF;
第三种
IF语句的多选择控制又称IF语句的嵌套,其书写格式为:
IF 条件 THEN
顺序处理语句;
ELSE
顺序处理语句;
……
ELSEIF 条件 THEN
顺序处理语句;
ELSE
顺序处理语句;
END IF;
2. CASE语句
CASE语句常用来描写总线行为、编码器和译码器的结构。与IF语句表可读性好,非常简洁。其书写格式为:
CASE 表达式 IS
WHEN 条件表达式=>顺序处理语句;
END CASE;
条件句中的“=>”不是操作符,只相当于“THEN”作用。
6 VHDL中的一些重要信号 6.1. 时钟信号和复位信号
1)时钟信号的描述
* 若进程的敏感信号是时钟信号,这时时钟信号出现在PROCESS后的括号中.
例: process (clock_signal)
begin
if (clock_edge_condition) then
signal_out<=signal_in
:
其它语句
:
end if;
end process;
* 在进程中用WAIT ON语句等待时钟
这样的电路没有敏感信号,进程通常停留在WAIT ON 语句上,只有时钟信号到来且满足一定条件时,其余语句才能执行.
例:
process
begin
wait on (clock_signal) until (clock_edge_condition)
signal_out<=signal_in;
其它语句
end process;
* 敏感表中只能有一个时钟信号
* wait on 语句只能放在进程的最前面或者最后面
* 时钟的边沿描述
描述时钟一定要指明是上升沿还是下降沿
上升沿到来的条件:
IF clk=’1’ AND clk’LAST_VALUE=’0’ AND clk’EVENT下降沿到来的条件:
IF clk=’0’ AND clk’LAST_VALUE=’1’ AND clk’EVENT
关于时钟信号的总结:
IF clock_signal=current_value AND
clock_signal’LAST AND
clock_siganl’EVENT
可以简单写为:
IF clock_signal=clock_siganl’EVENT AND current_value
6.2. 复位信号
*同步复位
当复位信号有效且在给定的时钟边沿到来时,触发器才被复位.
例1:
process (clock)
begin
if (clock_edge_condition) then
if (reset_condition) then
signal_out<=reset_value;
else
signal_out=signal_in;
:
其它语句
:
end if;
end if;
end process;
例2:
process(clock)
if (clock’event and clock=’1’) then
if reset=’1’ then
count<=’0’;
else
count<=count+1;
end if;
end if;
end process;
此例中,敏感表中只有时钟信号,因为只有时钟到来时才能复位.
* 异步复位
只要复位信号有效,触发器就被复位,所以敏感表中除时钟信号外,还需要复位信号
例1:
process(reset_signal,clock_signal)
begin
if (reset_signal) then
signal_out<=reset_value;
elsif (clock_event and clock_edge_condition) then
signal_out<=signal_in;
:
其它语句
:
end if;
end process;
例2:
process(clock,reset)
begin
if reset=’1’ then
count<=’0’;
elsif clock’event and clock=’1’ then
count<=count+1;
end if;
end process;
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- haog.cn 版权所有 赣ICP备2024042798号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务