VHDL:理解信号与变量、并行语句与顺序语句
初学VHDL,对一些问题总是感到困惑。比如,同样的赋值语句,在什么场合是并行的,什么时候又是顺序的?信号与变量有什么区别,为什么在PROCESS 里,对信号赋值的结果要等到进程挂起才起作用,而变量赋值却立刻起作用?其实,从语句产生的电路这个角度,可以更深刻地理解这些问题,下面是我自己摸索的一些理解方法,有不妥之处请大虾们指正!
1、赋值语句。
同样a <= b的赋值语句,会形成什么电路,起关键作用的是敏感信号。 a) 如果a <= b是在进程之外,那么隐含的敏感信号就是b,那么,这个赋值语句就形成一条连线。
b) 如果是在一个同步进程中,如if (rising_edge(CLK)) then a <= b,这时候,就会形成一个触发器,因为敏感信号是时钟边沿。
c) 如果敏感信号是一个电平信号,那么会形成一个锁存器。如一个不完整的if条件:if (cond = '1') then a <= b;
2、并行语句和顺序语句。
从形成的电路的角度,并行语句最终会有两种形式:
a) 并联或不相联的逻辑门或组合电路。因为是并联或不相联的,当然是同时执行,这个好理解。
b) 由同一个时钟边沿驱动的D触发器,不论D触发器之间是并联、串联或者不相连的。为什么呢?因为触发器是在同一个时钟边沿同时翻转的,也就是同时执行,所以本质上就是并行。
顺序语句只有一种情况,就是形成串联的逻辑门或组合电路。
3、信号与变量有什么不同?为什么信号赋值要等到进程挂起生效,变量赋值却立刻生效?
其实,了解了上一点并行语句和顺序语句所生成的电路,这个问题就好理解了。因为在同步进程里的并行语句,大多是形成b的情况,就是多个由同一时钟驱动的触发 器。由于从触发器的输入到翻转、输出需要一定的延时,这个延时基本就是进程执行完毕的时间,所以,触发器翻转后的输出在同一个时钟边沿中是看不到的,因为 它还没翻转过来呢。这就是信号赋值要等到进程挂起才生效的原因。
那为什么变量赋值却能立刻生效呢?这是因为,变量其实是为了帮助在同步进程中生成一些逻辑门或组合电路用的。看一看代码:var1 := not i1; var2 := var1 and i2 ; sig <= var2; 生成的RTL,就会看到,两个变量赋值语句其实生成了一个非门、一个与门。而且,输入信号i1和i2到var2这段是个组合电路,是不受时钟边沿控制的, 而到信号赋值语句sig <= var2,才形成一个D触发器。所以,这两个变量赋值语句生成了一个串联的非门和与门,那当然var2取到的是var1赋值后的值了。
最后顺便提一下为什么变量必须只能在进程内可见,我猜可能是为了防止在同步进程中输出异步信号,造成混乱吧。因为如果变量是外部可见的,如上面的 var2,那么var2的值就可以异步输出到进程外了。所以限制变量只能进程内可见后,要输出变量的值就只能赋值给一个信号,在同步进程中,就是加了一个 触发器了。
VHDL的并行语句用来描述一组并发行为,它是并发执行的,与程序的书写顺序无关。
进程语句
begin
进程语句包含在结构体中,一个结构体可以有多个进程语句,多个进程语句间是并行的,并可访问结构体或实体中定义的信号。因此进程语句称为并行描述语句。
进行语句结构内部所有语句都是顺序执行的
进程语句的启动是由process后敏感信号表中所标明的敏感信号触发来的。 各进程间的通信是由信号来传递的
语法如下:
标记:
process(敏感信号表)
变量说明语句;
begin
一组顺序语句;
end process 标记;
标记:为进程标号
敏感信号表:是进程用来读取所有敏感信号(包括端口)的列表。
变量说明:主要包括变量的数据类型说明、子程序说明等
从begin到end process之间是一组顺序执行语句。
敏感信号表
所谓敏感信号表:就是用来存放敏感信号的列表。在进程语句中,敏感信号指那些发生改变后能引起进程语句执行的信号。敏感信号表中可以使用一个或多个信号,当其中一个或多个信号值改变时,就在进程内部引起语句执行。敏感信号表也可忽略,但程序中必须有其他形式的敏感信号激励。例如wait、wait for、wait until和wait on。
进程语句的启动
在VHDL语言中,进程有两种工作状态:等待和执行。当敏感信号表中的信号没有变化时,进程处于等待状态;当敏感信号表中的信号有变化时,进程处于执行状态
进程语句的同步
同一个结构体中不仅可以有多个进程存在,同一个结构体中的多个进程还可以同步。VHDL中通常采用时钟信号来同步进程,具体方法是:结构体中的几个进程共用同一个时钟信号来进行激励。
并发信号赋值语句
信号赋值语句在进程内部出现时,它是一种顺序描述语句。
信号赋值语句在结构体的进程之外出现时,它将以一种并发语句的形式出现。它们在结构体中是并行执行的。
注意:并发信号赋值语句是靠事件来驱动的,因此对于并发信号赋值语句来说,只有当赋值符号“<=”右边的对象有事件发生时才会执行该语句。
条件信号赋值语句
语法结构:
目标信号<=表达式1 when 条件1 else
表达式2 when 条件2 else
表达式3 when 条件3 else
...
表达式n-1 when 条件n-1 else
表达式n;
VHDL语言程序执行到该语句时,首先要进行条件判断,之后才进行信号赋值。如果满足条件,就将该条件前面那个表达式的值赋给目标信号;如果不满足条件按,就继续判断,直到最后一个表达式,如果前面的条件均不满足就无条件的赋值给最后一个表达式,因为最后一个表达式赋值无需条件。
选择信号赋值语句
语法结构:
with 表达式 select
目标信号<=表达式1 when 选择条件1,
表达式2 when 选择条件2,
...
表达式n when 选择条件n;
该语句在赋值之前需要对条件进行判断,附和条件则赋值,否则继续判断,直到最后一个语句。选择赋值语句需要把表达式的值在条件中都列举出来。
元件例化语句
在VHDL中,引用元件或者模块的说明采用component语句,他的作用是在结构体说明部分说明引用的元件或者模块,是元件说明语句。
语法格式:
component 引用的元件名
generic 参数说明;
port 端口说明;
end componet;
引用的元件名:
是将一个设计现成的实体定义为一个元件,是已经设计好的实体名,用来制定要在结构体中使用的元件名称
如果结构体中要进行参数的传递,那么component语句中需要类属参数说明--可选项;
引用元件端口的说明,是已经设计好的实体端口名表;
元件说明语句在architecture和begin之间。
元件例化引用
采用componet语句对要引用的原件进行说明后,为了引用的元件正确地嵌入到高一层的结构体描述中,就必须把被引用的元件端口信号于结构体中相应端口信号正确地连接起来,这就是元件例化语句要实现的功能。
语法结构:
标号名:元件名
generic map(参数映射)
prot map(端口映射);
其中标号:是元件例化语句的惟一标识,结构体中的标号名应该是惟一的
generic map语句:它的功能是实现对参数的赋值操作,从而可以灵活地改变引用元件的参数,为可选项
prot map:它的功能是把引用元件的端口信号与实际连接的信号对应起来,从而进行元件的引用操作。
VHDL中,为了实现引用元件的端口信号与结构体中的实际信号相连接,往往采用两种映射方法:
1、位置映射方法:指port map语句中实际信号的书写顺序于componet语句中端口说明的信号书写语句顺序一致
2、名称映射方法:指在port map中将引用的元件的端口信号名称赋值给结构体中要使用例化元件的各个信号
(名称映射语句的书写要求不是十分严格,只要把映射的对应信号连接起来就可以,顺序可以颠倒)。
生成语句
规则结构
某些电路部分是由同类元件组成的阵列,这些同类元件叫规则结构,例如:随机RAM、只读ROM、移位寄存器等规则结构一般用生成语句来描述。
生成语句有两种形式:for_generate和if_generate
for_generate主要用来描述规则
if_generate主要用来描述结构在其端部表现出的不规则性,例如边界条件的特殊性
for_generate语句
标号:for 循环变量 in 离散范围 generate
并行处理语句;
end generate 标号;
标号:用来作为for_generate语句的唯一标识符,可选项;
循环变量:它的值在每次循环中都将发生变化;
离散范围:用来指定循环变量的取值范围,循环变量的取值将从取值范围最左边的值开始并且递增到取值范围的最右边,实际上限定了循环次数
for_generate与for_loop语句很类似,但二者有区别。for_loop语句的循环体中的处理语句是顺序的,而for_generate语句中处理的语句是并行处理的,具有并发性。
if_generate语句
标号:if 条件 generate
并行处理语句;
end generate 标号;
if_generate语句是并行处理语句,其中不允许出现else子语句
浅析硬件描述语言VHDL中的进程语句
作者简介:郭海青(19545-),甘肃酒泉人,副教授,主要从事电子测量技术和电子设计自动化(EDA)的教学和研究。
VHDL语言作为IEEE工业标准,在电子工程设计领域已成为通用的硬件描述语言 。它主要用于描述数字系统的结构、行为、功能和接口,几乎可承担起全部的数字系统设计任务。在VHDL语言中,进程(PROCESS)语句是最具特色的语句。它本身是一种并行语句,但它提供了一种用算法(顺序语句)描述硬件行为的方法。综合后的进程语句所对应的硬件逻辑模块,其工作方式可以是组合逻辑,也可以是时序逻辑,因此得到广泛的应用。
本文中,笔者总结了VHDL教学和实际设计的经验,较为详细地讨论了进程语句的特点,尤其对PROCESS结构中的顺序语句,所具有明显的顺序/并行运行的双重性〔1〕,从计算机的软件行为仿真的模拟过程而言的顺序性和实现的硬件的并行性进行了说明。通过实例以及分析,提出了正确应用的要点。希望对学习VHDL的读者有所帮助,并愿与同行切磋。
1.进程(PROCESS)语句格式及组成
1.1格式:
〔进程标号:〕PROCESS(敏感信号表)〔IS〕〔进程说明部分〕; BEGIN顺序描述语句END PROCESS〔进程标号〕;
1.2组成:进程语句有三部分组成,即:
① 进程说明部分,它主要定义一些局部量,如数据类型、常数、属性、子程序等。
② 顺序描述语句部分,用来描述硬件行为。③ 敏感信号表,用来激活进程,如果不列出敏感信号,则进程必需用显式的WAIT语句来激活。
2.进程的工作过程
当进程的敏感信号表中的任意信号发生变化时,此进程即被激活,开始顺序执行
进程中的顺序语句,当最后一条语句执行完毕,进程将被挂起,即自动返回到进程的第一条语句,等侍下一次敏感信号发生变化。因此,进程是一个无限循环的程序结构〔2〕,在进程中不必放置如软件语言中的返回语句。
3.进程的特点及应用要点:
3.1在同一个结构体中,可以有多个进程,多个进程之间是并行运行的。这是因为进程之间的通信,是通过定义在结构体中的、具有全局特性的数据对象“信号”来实现的。因此在任一进程的说明部分,不允许定义“信号”,而只能定义具有局部特性的数据对象“变量”。
3.2虽然同一个结构体中的多个进程之间是并行运行的,但同一进程中用于描述硬件行为的顺序语句则是顺序执行的〔1〕。
而需要注意的是,所谓顺序执行只不过是相对于计算机中的软件行为仿真的模拟过程而言,这并不意味着这些顺序语句对应的硬件结构具有相同的顺序性。因为在PROCESS结构中,顺序语句既可以描述时序逻辑,也可以描述组合逻辑。经综合、下载实现的硬件中,组合逻辑具有最典型的并行逻辑功能,而时序逻辑也并非是以顺序的方式工作的。这说明PROCESS结构中的顺序语句具有明显的顺序/并行运行的双重性。5F〗
3.3在不同进程中,不可以对同一信号赋值。因为在VHDL中,一条信号赋值语句就可以创建一个信号源〔3〕,当同一赋值目标处于不同进程中,其赋值是并行进行的,这使得赋值结果很复杂。可以看成是多个信号源连在一起,若处理不当,则会出现赋值操作冲突,使设计失败。
3.4在同一进程中,对同一信号多次赋值,只能是最后一次生效。因为对信号的赋值不是立即完成的,而是在进程结束时完成〔4〕。
例如设计一时序电路,其程序如〔程序1〕:
〔程序1〕——略去申明部分
entity li1 is
port (clock: in stdlogic;
outpot: out integer range 0 to 15 );
end li1;
architecture one of li1 is
signal B: integer range 0 to 15 :=0;
begin
process (clock)
begin
if clock'event and clock='1' then
B<=B+1;B<=B+2;B<=B+3;
end if;
end process;
outpot<=B;
end;
如从程序描述来看,当时钟的上升沿到来时,输出的值是在前一次的基础上加6。但对此程序通过编译后仿真的波形如图1,从仿真结果中清楚看到,在进程中虽对信号B进行了三次赋值,但只有B<=B+3是有效赋值,而B<=B+1和B<=B+2两次赋值都被忽略。
图1程序1仿真波形图
3.5在一个进程中,不能同时对时钟的上、下沿敏感。例如〔程序2〕在编译时,编译器将给出错误信息“process clocking is too complex”,同时此进程也是不可综合的。〔程序2〕——略去申明和实体部分
architecture one of li2 is
signal B: integer range 0 to 15 :=0;
begin
process (clock)
begin
if clock'event and clock='1' then
B<= B+1;
elsif clock'event and clock='0' then
B<= B+3;
end if;
end process;
outpot<= B;
end;
3.6在一个进程中,只能构成对应单一时钟信号的时序电路。所以,同步时序电路可用单个进程来描述,而异步时序电路则需多个进程实现。例如对图2所示的时序电路的描述〔程序3〕未能通过编译,而〔程序4〕是正确的描述。
图2异步时序电路原理图
〔程序3〕——略去申明和实体部分
architecture one of li3 is
signal Q1, Q2: stdlogic;
begin
process (clk, Q1)
begin
if risingedge (clk) then
Q1<= not (Q2 or A ) ;
elsif risingedge (Q1) then
Q2<= D ;
end if ;
end process ;
QQ<= Q2;
End ;〔程序4〕〔1〕——略去申明和实体部分 architecture one of li4 is
signal Q1,Q2: stdlogic ;
begin
pro1: process (clk) begin
if risingedge (clk) then
Q1<= not (Q2 or A ) ;
end if ;
end process ;
pro2:process (Q1)
begin
if risingedge (Q1) then
Q2<= D ; end if ;
end process ;
QQ<= Q2 ;End ;
4结束语
进程语句是VHDL语言中非常重要,且使用率很高的语句。虽然它的组成并不复杂,但在实际应用中,深入地了解语句特点和工作过程,正确地描述待设计电路并且得到正确的综合结果还是比较困难的,这需要在学习过程和大量的实际应用中不断积累总结经验,方可应用自如。
CPLD/FPGA设计流程主要包括电路设计与输入、功能仿真、综合、综合后仿真、实现、布线后仿真与验证及板级仿真验证与调试等主要步骤。电路设计与输入最常用的方法是硬件描述语言(HDL),其中影响最为广泛的是VHDL和Verilog HDL。通过这次培训笔者掌握了VHDL的基本概念、语句结构、语言现象及描述方法等,基本内容概括如下:VHDL主要部件分为两个层次,即硬件层次和软件层次。在硬件层次里主要的单元是实体(entity),它用来定义硬件外部接口;软件层次由软件包和软件包体构成,软件包对应了硬件层次的实体,软件包体对应了硬件层次的结构体。VHDL包含2大类语句,即顺序描述语句和并行描述语句;有3类数据对象,即变量、常量和信号;有4种运算符,分别为逻辑运算符、算术运算符、关系运算符和并置运算符;有5种预定义属性,包括值类属性、函数类属性、信号类属性、数据类型类属性及数据范围类属性。并行描述语句可以分为进程语句、并行信号赋值语句、并行断言语句、参数传递语句、元件例化语句和生成语句等6类。此外,笔者对VHDL语言的元素、结构、子结构、描述语句、预定义属性、配置以及常用的程序模块等7部分也有了一定的理解。VHDL中定义的标准数据类型有位和位矢量、布尔量、字符和字符串、整数、自然数和正整数、实数、时间及错误等级等8类;常用的数字电路模块有基本门电路、编码器、译码器、选择器、运算器、触发器、寄存器、计数器以及有限状态机等9类;顺序描述语句包含有信号和变量赋值语句、WAIT语句、IF语句、CASE语句、LOOP语句、RETURN语句、NULL语句、REPORT语句、跳出循环语句以及顺序断言语句等10种。
顺序执行是指编译器处理该语句时顺序执行,对应电路上可能会有前后级的关系,最多延迟几nS
百度搜索“爱华网”,专业资料,生活学习,尽在爱华网