三、 并发代码
VHDL中并发描述语句有WHEN和GENERATE。除此之外,仅包含AND, NOT, +, *和sll等逻辑、算术运算操作符的赋值语句也是并发执行的。在BLOCK中的代码也是并发执行的。
从本质上讲,VHDL代码是并行执行的。只有PROCESS, , 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语法结构:
assignment WHEN condition ELSE
assignment WHEN condition ELSE
…;
WITH/SELECT/WHEN语法结构
WITH identifier SELECT
assignment WHEN value,
assignemnt WHEN value,
…;
当使用WITH/SELECT/WHEN时,必须对所有可能出现的条件给予考虑,使用关键字OTHERS,如果在某些条件出现时不需要进行任何操作,那应该使用UNAFFECTED。
例:
————————————-with WHEN/ELSE——————————————-
Output <= “000” WHEN (inp = ‘0’ OR reset = ‘1’) ELSE
“001” WHEN ctl = ‘1’ ELSE
“010”;
———————————–with WITH/SELECT/WHEN——————————–
WITH control SELECT
Output <= “000” WHEN reset,
“111” WHEN set,
UNAFFECTED WHEN OTHERS;
对于WHEN语句,WHEN value的描述方式有以下几种:
WHEN value –针对单个值进行判断
WHEN value1 to value2 –针对取值范围进行判断
WHEN value1 | value2 | … –针对多个值进行判断
GENERATE语句
GENERATE语句和顺序描述语句中的LOOP语句一样用于循环执行某项操作,通常与FOR一起使用。语法结构如下:
label: FOR identifier IN range GENERATE
(concurrent assignments)
END GENERATE
GENERATE语句还有另一种形式:IF/GENERATE,此处不允许使用ELSE。IF/GENERATE可以嵌套在FOR/GENERATE内部使用。反之亦然。
Label1: FOR identifier IN range GENERATE
……
Label2: IF condition GENERATE
(concurrent assignments)
END GENERATE;
……
END GENERATE;
例:
SIGNAL x: BIT_VECTOR(7 DOWNTO 0);
SIGNAL y: BIT_VECTOR(15 DOWNTO 0);
SIGNAL z: BIT_VECTOR(7 DOWNTO 0);
……
G1: FOR i IN x’RANGE GENERATE
z(i) <= x(i) AND y(i+8);
END GENERATE;
GENERATE中循环操作的上界和下界必须是静态的,在使用过程中还要注意多值驱动问题。
例:
OK: FOR i IN 0 TO 7 GENERATE
Output(i) <= ‘1’ WHEN (a(i) AND b(i)) = ‘1’ ELSE ‘0’;
END GENERATE;
—————————————————————————
NotOK: FOR i IN 0 TO 7 GENERATE
accum <= “1111_1111” WHEN (a(i) AND b(i)) = ‘1’ ELSE “0000_0000”;
END GENERATE;
—————————————————————-
NotOK: FOR i IN 0 TO 7 GENERATE
Accum <= accum + 1 WHEN x(i) = ‘1’;
END GENERATE;
—————————————————————-
块语句(BLOCK)
VHDL中有两种BLOCK:simple BLOCK和guarded BLOCK。
n Simple BLOCK
Simple BLOCK仅仅是对原有代码进行区域分割,增强整个代码的可读性和可维护性。语法结构如下:
label:BLOCK
[ declarative part]
BEGIN
(concurrent statement)
END BLOCK label;
—————————————————————————————————-
ARCHITETURE example…
BEGIN
…
block1: BLOCK
BEGIN
…
END BLOCK block1;
…
block2: BLOCK
BEGIN
…
END BLOCK block2;
…
END example;
—————————————————————————————–
例:
b1: BLOCK
SIGNAL a: STD_LOGIC;
BEGIN
a <= input_sig WHEN ena = ‘1’ ELSE ‘z’;
END BLOCK b1;
———————————————————————————————————————-
无论是simple BLOCK还是guarded BLOCK,其内部都可以嵌套其他的BLOCK语句,相应的语法结构如下:
label1: BLOCK
[顶层BLOCK声明部分]
BEGIN
[顶层BLOCK并发描述部分]
label2: BLOCK
[嵌套BLOCK声明部分]
BEGIN
[嵌套BLOCK并发描述部分]
END BLOCK label2;
[顶层BLOCK其他并发描述语句]
END BLOCK label1;
———————————————————————————————————
n Guarded BLOCK
多了一个卫式表达式,只有当卫式表达式为真时才能执行。语法结构如下:
Label: BLOCK(卫式表达式)
[声明部分]
BEGIN
(卫式语句和其他并发描述语句)
END BLOCK label;