VHDL语法简单总结.docx

上传人:b****6 文档编号:13593632 上传时间:2023-06-15 格式:DOCX 页数:28 大小:26.22KB
下载 相关 举报
VHDL语法简单总结.docx_第1页
第1页 / 共28页
VHDL语法简单总结.docx_第2页
第2页 / 共28页
VHDL语法简单总结.docx_第3页
第3页 / 共28页
VHDL语法简单总结.docx_第4页
第4页 / 共28页
VHDL语法简单总结.docx_第5页
第5页 / 共28页
VHDL语法简单总结.docx_第6页
第6页 / 共28页
VHDL语法简单总结.docx_第7页
第7页 / 共28页
VHDL语法简单总结.docx_第8页
第8页 / 共28页
VHDL语法简单总结.docx_第9页
第9页 / 共28页
VHDL语法简单总结.docx_第10页
第10页 / 共28页
VHDL语法简单总结.docx_第11页
第11页 / 共28页
VHDL语法简单总结.docx_第12页
第12页 / 共28页
VHDL语法简单总结.docx_第13页
第13页 / 共28页
VHDL语法简单总结.docx_第14页
第14页 / 共28页
VHDL语法简单总结.docx_第15页
第15页 / 共28页
VHDL语法简单总结.docx_第16页
第16页 / 共28页
VHDL语法简单总结.docx_第17页
第17页 / 共28页
VHDL语法简单总结.docx_第18页
第18页 / 共28页
VHDL语法简单总结.docx_第19页
第19页 / 共28页
VHDL语法简单总结.docx_第20页
第20页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

VHDL语法简单总结.docx

《VHDL语法简单总结.docx》由会员分享,可在线阅读,更多相关《VHDL语法简单总结.docx(28页珍藏版)》请在冰点文库上搜索。

VHDL语法简单总结.docx

VHDL语法简单总结

VHDL语法简单总结

一个VHDL程序代码包含实体(entity)、结构体(architecture)、配置(configuration)、程序包(package)、库(library)等。

 

 

一、        数据类型

1.用户自定义数据类型

使用关键字TYPE,例如:

TYPEmy_integerISRANGE-32TO32;

–用户自定义的整数类型的子集

TYPEstudent_gradeISRANGE0TO100;

–用户自定义的自然数类型的子集

TYPEstateIS(idle,forward,backward,stop);

–枚举数据类型,常用于有限状态机的状态定义

一般来说,枚举类型的数据自动按顺序依次编码。

2.子类型

在原有已定义数据类型上加一些约束条件,可以定义该数据类型的子类型。

VHDL不允许不同类型的数据直接进行操作运算,而某个数据类型的子类型则可以和原有类型数据直接进行操作运算。

子类型定义使用SUBTYPE关键字。

3.数组(ARRAY)

ARRAY是将相同数据类型的数据集合在一起形成的一种新的数据类型。

TYPEtype_nameISARRAY(specification)OFdata_type;

–定义新的数组类型语法结构

SIGNALsignal_name:

type_name[:

=initial_value];

–使用新的数组类型对SIGNAL,CONSTANT,VARIABLE进行声明

例如:

TYPEdelay_linesISARRAY(L-2DOWNTO0)OFSIGNED(W_IN-1DOWNTO0);

–滤波器输入延迟链类型定义

TYPEcoeffsISARRAY(L-1DOWNTO0)OFSIGNED(W_COEF-1DOWNTO0);

–滤波器系数类型定义

SIGNALdelay_regs:

delay_lines;  –信号延迟寄存器声明

CONSTANTcoef:

coeffs:

=(    );–常量系数声明并赋初值

4.端口数组

在定义电路的输入/输出端口时,有时需把端口定义为矢量阵列,而在ENTITY中不允许使用TYPE进行类型定义,所以必须在包集(PACKAGE)中根据端口的具体信号特征建立用户自定义的数据类型,该数据类型可以供包括ENTITY在内的整个设计使用。

—————————————PACKAGE———————————-

libraryieee;

useieee.std_logic_1164.all;

——————————————

PACKAGEmy_data_typesIS

     TYPEvector_arrayISARRAY(naturalrange<>)OFSTD_LOGIC_VECTOR(7DOWNTO0);–声明8位的数组

ENDmy_data_types;

———————————–MainCode—————————————

libraryieee;

useieee.std_logic_1164.all;

usework.my_data_types.all;–用户自定义包集

——————————————————————

ENTITYmuxIS

PORT(inp:

INvector_array(0to3);

ENDmux;

——————————————————————————-

5.有符号数和无符号数

要使用SIGNED和UNSIGNED类型数据,必须在代码开始部分声明ieee库中的包集std_logic_arith。

它们支持算术运算但不支持逻辑运算。

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

……

SIGNALa:

INSIGNED(7DOWNTO0);

SIGNALb:

INSIGNED(7DOWNTO0);

SIGNALx:

INSIGNED(7DOWNTO0);

……

v<=a+b;

w<=aANDb;  –非法(不支持逻辑运算)

——————————————————————————-

STD_LOGIC_VECTOR类型的数据不能直接进行算术运算,只有声明了std_logic_signed和std_logic_unsigned两个包集后才可以像SIGNED和UNSIGNED类型的数据一样进行算术运算。

6.数据类型转换

在ieee库的std_logic_arith包集中提供了许多数据类型转换函数:

1.conv_integer(p):

将数据类型为INTEGER,UNSIGNED,SIGNED,STD_ULOGIC或STD_LOGIC的操作数p转换成INTEGER类型。

不包含STD_LOGIC_VECTOR。

2.conv_unsigned(p,b):

将数据类型为INTEGER,UNSIGNED,SIGNED或STD_ULOGIC的操作数p转换成位宽为b的UNSIGNED类型数据。

3.conv_signed(p,b):

将数据类型为INTEGER,UNSIGNED,SIGNED或STD_ULOGIC的操作数p转换成位宽为b的SIGNED类型的数据。

4.conv_std_logic_vector(p,b):

将数据类型为INTEGER,UNSIGNED,SIGNED或STD_LOGIC的操作数p转换成位宽为b的STD_LOGIC_VECTOR类型的数据。

 

二、        运算操作符和属性

1.       运算操作符

l  赋值运算符

赋值运算符用来给信号、变量和常数赋值。

<=    用于对SIGNAL类型赋值;

:

=     用于对VARIABLE,CONSTANT和GENERIC赋值,也可用于赋初始值;

=>    用于对矢量中的某些位赋值,或对某些位之外的其他位赋值(常用OTHERS表示)。

例:

SIGNALx:

STD_LOGIC;

VARIABLEy:

STD_LOGIC_VECTOR(3DOWNTO0);  –最左边的位是MSB

SIGNALw:

STD_LOGIC_VECTOR(0TO7);  –最右边的位是MSB

x<=‘1’;

y:

=“0000”;

w<=“1000_0000”;  –LSB位为1,其余位为0

w<=(0=>‘1’,OTHERS=>‘0’);  –LSB位是1,其他位是0

l  逻辑运算符

操作数必须是BIT,STD_LOGIC或STD_ULOGIC类型的数据或者是这些数据类型的扩展,即BIT_VECTOR,STD_LOGIC_VECTOR,STD_ULOGIC_VECTOR。

VHDL的逻辑运算符有以下几种:

(优先级递减)

Ÿ   NOT——取反

Ÿ   AND——与

Ÿ   OR——或

Ÿ   NAND——与非

Ÿ   NOR——或非

Ÿ   XOR——异或

l  算术运算符

操作数可以是INTEGER,SIGNED,UNSIGNED,如果声明了std_logic_signed或std_logic_unsigned,可对STD_LOGIC_VECTOR类型的数据进行加法或减法运算。

+——加

-          ——减

*——乘

/——除

**——指数运算

MOD——取模

REM——取余

ABS——取绝对值

加,减,乘是可以综合成逻辑电路的;除法运算只在除数为2的n次幂时才能综合,此时相当于对被除数右移n位;对于指数运算,只有当底数和指数都是静态数值(常量或GENERIC参数)时才是可综合的;对于MOD运算,结果的符号同第二个参数的符号相同,对于REM运算,结果的符号同第一个参数符号相同。

l  关系运算符

=,/=,<,>,<=,>=

左右两边操作数的类型必须相同。

l  移位操作符

<左操作数><移位操作符><右操作数>

其中左操作数必须是BIT_VECTOR类型的,右操作数必须是INTEGER类型的(可以为正数或负数)。

VHDL中移位操作符有以下几种:

u  sll  逻辑左移  –数据左移,右端补0;

u  srl  逻辑右移  –数据右移,左端补0;

u  sla  算术左移  –数据左移,同时复制最右端的位,填充在右端空出的位置;

u  sra  算术右移  –数据右移,同时复制最左端的位,填充在左端空出的位置;

u  rol  循环逻辑左移—数据左移,从左端移出的位填充到右端空出的位置上;

u  ror  循环逻辑右移–数据右移,从右端移出的位填充到左端空出的位置上。

例:

x<=“01001”,那么:

y<=xsll2;  – 逻辑左移2位,y<=”00100”

y<=xsla2;  – 算术左移2位,y<=”00111”

y<=xsrl3;  – 逻辑右移3位,y<=”00001”

y<=xsra3;  – 算术右移3位,y<=”00001”

y<=xrol2;  – 循环左移2位,y<=”00101”

y<=xsrl-2;  –相当于逻辑左移2位

l  并置运算符

用于位的拼接,操作数可以是支持逻辑运算的任何数据类型。

有以下两种:

²  &

²  (,,,)

与Verilog中{}的功能一样。

2.       属性(ATTRIBUTE)

l  数值类属性

数值类属性用来得到数组、块或一般数据的相关信息,例如可用来获取数组的长度和数值范围等。

以下是VHDL中预定义的可综合的数值类属性:

d’LOW             –返回数组索引的下限值

d’HIGH            –返回数组索引的上限值

d’LEFT             –返回数组索引的左边界值

d’RIGHT            –返回数组索引的右边界值

d’LENGTH      –返回矢量的长度值

d’RANGE          –返回矢量的位宽范围

d’REVERSE_RANGE  –按相反的次序返回矢量的位宽范围

例:

定义信号SIGNALd:

STD_LOGIC_VECTOR(7DOWNTO0);

则有:

d’LOW=0,d’HIGH=7,d’LEFT=7,d’RIGHT=0,d’LENGTH=8, d’RANGE=(7DOWNTO0),d’REVERSE_RANGE=(0TO7).

l  信号类属性

对于信号s,有以下预定义的属性(可综合的):

s’EVENT            若s的值发生变化,则返回布尔量TRUE,否则返回FALSE

s’STABLE         若s保持稳定,则返回TRUE,否则返回FALSE

例:

clk的上升沿判断

IF(clk’EVENTANDclk=‘1’)

IF(NOTclk’STABLEANDclk=‘1’)

WAITUNTIL(clk’EVENTANDclk=‘1’)

3.       通用属性语句

GENERIC语句提供了一种指定常规参数的方法,所指定的参数是静态的,增加了代码的可重用性,类似于Verilog中的parameter与defparam。

GENERIC语句必须在ENTITY中进行声明,由GENERIC语句指定的参数是全局的,不仅可在ENTITY内部使用,也可在后面的整个设计中使用。

语法结构如下:

GENERIC(parameter_name:

parameter_type:

=parameter_value);

用GENERIC语句指定多个参数:

GENERIC(n:

INTEGER:

=8;vector:

BIT_VECTOR:

=“0000_1111”);

 

 

三、        并发代码

VHDL中并发描述语句有WHEN和GENERATE。

除此之外,仅包含AND,NOT,+,*和sll等逻辑、算术运算操作符的赋值语句也是并发执行的。

在BLOCK中的代码也是并发执行的。

从本质上讲,VHDL代码是并行执行的。

只有PROCESS,FUNCTION,PROCEDURE内部的代码才是顺序执行的。

但是当它们作为一个整体时,与其他模块之间又是并行执行的。

并发代码称为“数据流”代码。

通常我们只能用并发描述语句来实现组合逻辑电路,为了实现时序逻辑电路,必须使用顺序描述语句。

事实上,使用顺序描述语句可以同时实现组合逻辑电路和时序逻辑电路。

在并发代码中可以使用以下各项:

Ø  运算操作符

Ø  WHEN语句(WHEN/ELSE或WITH/SELECT/WHEN)

Ø  GENERATE语句

Ø  BLOCK语句

使用运算操作符

运算类型

运算操作符

操作数类型

逻辑运算

NOT,AND,NAND,OR

NOR,XOR,XNOR

BIT,BIT_VECTOR,STD_LOGIC,STD_LOGIC_VECTOR

STD_ULOGIC,STD_ULOGIC_VECTOR

算术运算符

+,—,*,/,**

INTEGER,SIGNED,UNSIGNED

比较运算符

=,/=,<,>,<=,>=

任意数据类型

移位运算符

sll,srl,sla,sra,rol,ror

BIT_VECTOR

并置运算符

&,(,,,)

STD_LOGIC,STD_LOGIC_VECTOR,STD_ULOGIC

STD_ULOGIC_VECTOR,SIGNED,UNSIGNED

WHEN语句

WHEN语句是一种基本的并发描述语句,有两种形式:

WHEN/ELSE和WITH/SELECT/WHEN。

WHEN/ELSE语法结构:

assignmentWHENconditionELSE

assignmentWHENconditionELSE

…;

WITH/SELECT/WHEN语法结构

WITHidentifierSELECT

assignmentWHENvalue,

assignemntWHENvalue,

…;

当使用WITH/SELECT/WHEN时,必须对所有可能出现的条件给予考虑,使用关键字OTHERS,如果在某些条件出现时不需要进行任何操作,那应该使用UNAFFECTED。

例:

 

————————————-withWHEN/ELSE——————————————-

Output<=“000”WHEN(inp=‘0’ORreset=‘1’)ELSE

                “001”WHENctl=‘1’ELSE

                “010”;

———————————–withWITH/SELECT/WHEN——————————–

WITHcontrolSELECT

       Output<=“000”WHENreset,

                       “111”WHENset,

                       UNAFFECTEDWHENOTHERS;

对于WHEN语句,WHENvalue的描述方式有以下几种:

WHENvalue                           –针对单个值进行判断

WHENvalue1tovalue2          –针对取值范围进行判断

WHENvalue1|value2|…      –针对多个值进行判断

GENERATE语句

GENERATE语句和顺序描述语句中的LOOP语句一样用于循环执行某项操作,通常与FOR一起使用。

语法结构如下:

label:

FORidentifierINrangeGENERATE

       (concurrentassignments)

ENDGENERATE

GENERATE语句还有另一种形式:

IF/GENERATE,此处不允许使用ELSE。

IF/GENERATE可以嵌套在FOR/GENERATE内部使用。

反之亦然。

Label1:

FORidentifierINrangeGENERATE

……

       Label2:

IFconditionGENERATE

              (concurrentassignments)

       ENDGENERATE;

……

ENDGENERATE;

例:

SIGNALx:

BIT_VECTOR(7DOWNTO0);

SIGNALy:

BIT_VECTOR(15DOWNTO0);

SIGNALz:

BIT_VECTOR(7DOWNTO0);

……

G1:

FORiINx’RANGEGENERATE

z(i)<=x(i)ANDy(i+8);

ENDGENERATE;

GENERATE中循环操作的上界和下界必须是静态的,在使用过程中还要注意多值驱动问题。

例:

OK:

FORiIN0TO7GENERATE

       Output(i)<=‘1’WHEN(a(i)ANDb(i))=‘1’ELSE‘0’;

ENDGENERATE;

—————————————————————————

NotOK:

FORiIN0TO7GENERATE

       accum<=“1111_1111”       WHEN    (a(i)ANDb(i))=‘1’ELSE“0000_0000”;

ENDGENERATE;

—————————————————————-

NotOK:

FORiIN0TO7GENERATE

       Accum<=accum+1WHENx(i)=‘1’;

ENDGENERATE;

—————————————————————-

块语句(BLOCK)

VHDL中有两种BLOCK:

simpleBLOCK和guardedBLOCK。

n  SimpleBLOCK

SimpleBLOCK仅仅是对原有代码进行区域分割,增强整个代码的可读性和可维护性。

语法结构如下:

label:

BLOCK

       [ declarativepart]

BEGIN

       (concurrentstatement)

ENDBLOCKlabel;

—————————————————————————————————-

ARCHITETUREexample…

BEGIN

       …

       block1:

BLOCK

       BEGIN

              …

       ENDBLOCKblock1;

       …

       block2:

BLOCK

       BEGIN

              …

ENDBLOCKblock2;

ENDexample;

—————————————————————————————–

 

 

例:

b1:

BLOCK

       SIGNALa:

STD_LOGIC;

BEGIN

       a<=input_sigWHENena=‘1’ELSE‘z’;

ENDBLOCKb1;

———————————————————————————————————————-

无论是simpleBLOCK还是guardedBLOCK,其内部都可以嵌套其他的BLOCK语句,相应的语法结构如下:

label1:

BLOCK

       [顶层BLOCK声明部分]

BEGIN

       [顶层BLOCK并发描述部分]

label2:

BLOCK

              [嵌套BLOCK声明部分]

BEGIN

       [嵌套BLOCK并发描述部分]

       ENDBLOCKlabel2;

[顶层BLOCK其他并发描述语句]

ENDBLOCKlabel1;

———————————————————————————————————

n  GuardedBLOCK

多了一个卫式表达式,只有当卫式表达式为真时才能执行。

语法结构如下:

Label:

BLOCK(卫式表达式)

       [声明部分]

BEGIN

       (卫式语句和其他并发描述语句)

ENDBLOCKlabel;

 

 

四、        顺序代码

在PROCESS,FUNCTION,PROCEDURE内部的代码都是顺序执行的,这样的语句包括IF,WAIT,CASE和LOOP。

变量只能在顺序代码中使用,相对于信号而言,变量是局部的,所以它的值不能传递到PROCESS,FUNCTION和PROCEDURE的外部。

1.      进程(PROCESS)

进程内部经常使用IF,WAIT,CASE或LOOP语句。

PROCESS具有敏感信号列表(sensitivitylist),或者使用WAIT语句进行执行条件的判断。

PROCESS必须包含在主代码段中,当敏感信号列表中的某个信号发生变化时(或者当WAIT语句的条件得到满足时),PROCESS内部的代码就顺序执行一次。

语法结构如下:

[label:

]PROCESS(sensitivitylist)

       [VARIABLEnametype[range][:

=initial_value;]]

BEGIN

       (顺序执行的代码)

ENDPROCESS[label];

如果要在PROCESS内部使用变量,则必须在关键字BEGIN之前的变量声明部分对其进行定义。

变量的初始值是不可综合的,只用于仿真。

在设计同步电路时,要对某些信号边沿的跳变进行监视(时钟的上升沿或下降沿)。

通常使用EVENT属性来监视一个信号是否发生了变化。

2.      信号和变量

信号可在PACKAGE,ENTITY和ARCHITECTURE中声明,而变量只能在一段顺序描述代码的内部声明。

因此,信号通常是全局的,变量通常是局部的。

赋予变量的值是立刻生效的,在后续的代码中,此变量将使用新的变量值,而信号的值通常只有在整个PROCESS执行完毕后才开始生效。

3.      IF语句

IF/ELSE语句在综合时可能会产生不必要的优先级解码电路。

IF语句语法结构如下:

IFconditionsTHENassignments;

ELSIFconditionsTHENassignments;

ELSEassignments;

ENDIF;

————————————————————————————————

例:

IF(x

=“1

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 总结汇报 > 其它

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2