<返回更多

VHDL 编程常用语法及技巧汇总-命名规范及信号变量常量

2022-11-17  今日头条  newpowerleader
加入收藏

引言

VHDL编程语言语法内容很多很杂,包括用于编程的规定、用于仿真的规定以及用于描述的规定。对于刚刚接触VHDL语言的设计者而言,拿到厚厚的VHDL编程语言书籍,往往有无从下手感觉,其实对于使用VHDL很久的人来讲,也不一定会使用VHDL很多编程规范,今天对VHDL常用的编程规范进捋一捋。

命名规范

VHDL语言中的信号、变量或者常量都必须有一个属于自己的名字,即标识符,然后才能在程序中进行引用。而VHDL语法中的命名规则如下:

1、标识符中只能包含字符、数字和下划线,即”A-Z”,”a-z”,”0-9”,”_”;

2、标识符必须以字符开头,即开头符号只能是”A-Z”,”a-z”。

signal、variable和constant 定义和使用

vhdl编程语言对信号、变量或常量大小不敏感。signal、variable和constant 是vhdl三种经常使用的赋值对象。所有赋值对象都遵循先声明后使用原则。特别说明:常量是不能单独赋值的,仅仅能在声明的同时被初始化赋值。

signal

signal 中文意思为“信号” ,一般对应电路中特定的物理连线或存储单元。当程序中需要用到signal时,我们一般需要在VHDL基本程序框架中的architecture语法的声明与定义部分先声明一个signal,然后才能在architecture的语句部分使用它。 Signal的声明语法如下:

声明1

signal 信号名 :=初值 ; – 有初值

需要对signal 信号赋初值,只能定义一个信号名,eg

signal state : std_logic_vector(3 downto 0):=x"0";

声明2

signal 信号名:信号类型 ; – 无初值

signal state1: std_logic_vector(4 downto 0);

signal cnt: integer range 0 to 31;

声明3

如果有多个同样类型的信号需要声明,也可以用这样的语法:

signal 信号名1,信号名2,信号名3: 信号类型 ; – 多个信号名之间用逗号隔开

signal state11,state12: std_logic_vector(4 downto 0);

signal cnt1,cnt2: integer range 0 to 31;

特殊的声明-端口信号声明

entity语法中的port语法结构中的in、out、buffer或者inout类型的端口,虽然没有用关键字“signal”来声明,但它们其实都是signal类型的,并且同类型的端口也支持逗号分隔单行书写的方法。

entity div_des is

port

(

clk : in std_logic;

rst_n : in std_logic;

numer32 : in std_logic_vector( 31 downto 0);

demoniator32 : in std_logic_vector( 31 downto 0);

quotient32 : out std_logic_vector( 31 downto 0);

remainer32 : out std_logic_vector( 31 downto 0)

);

end div_des;

entity div_des is

port

(

clk,rst_n : in std_logic;

numer32 : in std_logic_vector( 31 downto 0);

demoniator32 : in std_logic_vector( 31 downto 0);

quotient32 : buffer std_logic_vector( 31 downto 0);

remainer32 : out std_logic_vector( 31 downto 0)

);

end div_des;

特殊声明-package 中声明signal

在library里的package语法中,也可以声明signal。

package my pkg is

type byte is range 0 to 255; ---定义byte的范围

subtye nibyte is byte range 0 to 15; 定义子类型

constant byte_ff: bcd:=255;

signal added: nibabc;

component byte_adder

port

(

a,b: in byte;

c: out byte;

overflow: out boolean

);

end component;

function my_fun (a: in byte)

return byte;

end my pkg;

Variable

Variable即是“变量”的意思,它不具有特定的物理意义,对应关系也不太直接,通常只代表暂存某些值的载体。** 在之前介绍的VHDL基本程序框架中,可以看到variable出现在process语句中,作为process的局部变量来使用。** 当程序中要用到variable时,只需要在process语法的敏感量列表与begin关键字之间先声明一个variable,然后就能在process的语句体中使用它。Variable的声明语法如下:

特别强调:变量只能在进程、function和procedure 语法结构中进行先声明后使用!

变量定义与信号定义类似,除了关键字和声明的位置不同外,其余定义都相同!

 

Constant

Constant即是“常量”的意思,它具有特定的物理意义,通常对应数字电路中的电源或者地。Constant能出现在所有signal和variable出现的场合中,它的声明语法如下:

constant : := ;

可以注意到,常量是不能单独赋值的,仅仅能在声明的同时被初始化赋值。

总结一下:信号、变量和常量之间差别:

差别一:赋值符号不同

变量声明使用variable,赋值符号位:=

而信号声明用signal,赋值符号为<=

差别二:使用位置不同或作用的范围不同

1、变量只能用在进程函数体,子程序内部
2、信号不能再进程中声明,信号用在结构体、实体、程序包。

差别三:敏感信号表中只能为信号,不能为变量。

在一个进程中,变量及时赋值,信号在进程结束后赋值。
(1)loop语句中,若在一个循环体内需要多次对某一个数据操作,则必须用变量,因为对信号赋值进行多次赋值只在最后一次才会有效。

(2)数组的索引(index)只能用变量。如果使用信号则编译会报错

编程心得

(1)变量赋值无延时是针对进程运行而言的,只是一个理想值,对于变量的操作往往被综合成为组合逻辑的形式,而硬件上的组合逻辑必然存在输入到输出延时。当进程内关于变量的操作越多,其组合逻辑就会变得越大越复杂。假设在一个进程内,有关于变量的3个 级连操作,其输出延时 分别为5ns,6ns,7ns,则其最快的时钟只能达到18ns。相反,采用信号编程,在时钟控制下,往往综合成触发器的形式,特别是对于FPGA芯片而言,具有丰富的触发器结构,易形成流水作业,其时钟频率只受控于延时最大的那一级,而不会与变量一样层层累积。假设某个设计为3级流水作业,其每一级延时分别为10ns,11ns,12ns,则其最快时钟可达12ns。因此,采用信号反而更能提高设计的速度。

(2)由于变量不具备信息的相关性,只有当前值,因此也无法在仿真时观察其波形和状态改变情况,无法对设计的运行情况有效验证,而测试验证工作量往往会占到整个设计70%~80%的工作量,采用信号则不会存在这类问题。

(3)变量有效范围只能局限在单个进程或子程序中,要想将其值带出与其余进程、子模块之间相互作用,必须借助信号,这在一定程度上会造成代码不够简洁,可读性下降等缺点。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>