一個(gè)VHDL程序代碼包含實(shí)體(entity)、結(jié)構(gòu)體(architecture)、配置(configuration)、程序包(package)、庫(library)等。
一、數(shù)據(jù)類型
1.用戶自定義數(shù)據(jù)類型
使用關(guān)鍵字TYPE,例如:
TYPE my_integer IS RANGE -32 TO 32;
–用戶自定義的整數(shù)類型的子集
TYPE student_grade IS RANGE 0 TO 100;
–用戶自定義的自然數(shù)類型的子集
TYPE state IS (idle, forward, backward, stop);
–枚舉數(shù)據(jù)類型,常用于有限狀態(tài)機(jī)的狀態(tài)定義
一般來說,枚舉類型的數(shù)據(jù)自動(dòng)按順序依次編碼。
2.子類型
在原有已定義數(shù)據(jù)類型上加一些約束條件,可以定義該數(shù)據(jù)類型的子類型。VHDL不允許不同類型的數(shù)據(jù)直接進(jìn)行操作運(yùn)算,而某個(gè)數(shù)據(jù)類型的子類型則可以和原有類型數(shù)據(jù)直接進(jìn)行操作運(yùn)算。
子類型定義使用SUBTYPE關(guān)鍵字。
3.數(shù)組(ARRAY)
ARRAY是將相同數(shù)據(jù)類型的數(shù)據(jù)集合在一起形成的一種新的數(shù)據(jù)類型。
TYPE type_name IS ARRAY (specification) OF data_type;
–定義新的數(shù)組類型語法結(jié)構(gòu)
SIGNAL signal_name: type_name [:= initial_value];
–使用新的數(shù)組類型對(duì)SIGNAL,CONSTANT, VARIABLE進(jìn)行聲明
例如:
TYPE delay_lines IS ARRAY (L-2 DOWNTO 0) OF SIGNED (W_IN-1 DOWNTO 0);
–濾波器輸入延遲鏈類型定義
TYPE coeffs IS ARRAY (L-1 DOWNTO 0) OF SIGNED (W_COEF-1 DOWNTO 0);
–濾波器系數(shù)類型定義
SIGNAL delay_regs: delay_lines;– 信號(hào)延遲寄存器聲明
CONSTANT coef: coeffs := (); –常量系數(shù)聲明并賦初值
4.端口數(shù)組
在定義電路的輸入/輸出端口時(shí),有時(shí)需把端口定義為矢量陣列,而在ENTITY中不允許使用TYPE進(jìn)行類型定義,所以必須在包集(PACKAGE)中根據(jù)端口的具體信號(hào)特征建立用戶自定義的數(shù)據(jù)類型,該數(shù)據(jù)類型可以供包括ENTITY在內(nèi)的整個(gè)設(shè)計(jì)使用。
—————————————PACKAGE———————————-
library ieee;
use ieee.std_logic_1164.all;
——————————————
PACKAGE my_data_types IS
TYPE vector_array IS ARRAY (natural range <>) OF STD_LOGIC_VECTOR(7 DOWNTO 0); –聲明8位的數(shù)組
END my_data_types;
———————————–Main Code—————————————
library ieee;
use ieee.std_logic_1164.all;
use work.my_data_types.all; –用戶自定義包集
——————————————————————
ENTITY mux IS
PORT (inp: IN vector_array(0 to 3);
END mux;
——————————————————————————-
5.有符號(hào)數(shù)和無符號(hào)數(shù)
要使用SIGNED和UNSIGNED類型數(shù)據(jù),必須在代碼開始部分聲明ieee庫中的包集std_logic_arith。它們支持算術(shù)運(yùn)算但不支持邏輯運(yùn)算。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
……
SIGNAL a: IN SIGNED (7 DOWNTO 0);
SIGNAL b: IN SIGNED (7 DOWNTO 0);
SIGNAL x: IN SIGNED (7 DOWNTO 0);
……
v <= a + b;
w <= a AND b;–非法(不支持邏輯運(yùn)算)
——————————————————————————-
STD_LOGIC_VECTOR類型的數(shù)據(jù)不能直接進(jìn)行算術(shù)運(yùn)算,只有聲明了std_logic_signed和std_logic_unsigned兩個(gè)包集后才可以像SIGNED和UNSIGNED類型的數(shù)據(jù)一樣進(jìn)行算術(shù)運(yùn)算。
6.數(shù)據(jù)類型轉(zhuǎn)換
在ieee庫的std_logic_arith包集中提供了許多數(shù)據(jù)類型轉(zhuǎn)換函數(shù):
1. conv_integer(p): 將數(shù)據(jù)類型為INTEGER,UNSIGNED,SIGNED,STD_ULOGIC或STD_LOGIC的操作數(shù)p轉(zhuǎn)換成INTEGER類型。不包含STD_LOGIC_VECTOR。
2. conv_unsigned(p,b):將數(shù)據(jù)類型為INTEGER,UNSIGNED,SIGNED或STD_ULOGIC的操作數(shù)p轉(zhuǎn)換成位寬為b的UNSIGNED類型數(shù)據(jù)。
3. conv_signed(p,b):將數(shù)據(jù)類型為INTEGER, UNSIGNED, SIGNED或STD_ULOGIC的操作數(shù)p轉(zhuǎn)換成位寬為b的SIGNED類型的數(shù)據(jù)。
4. conv_std_logic_vector(p, b):將數(shù)據(jù)類型為INTEGER, UNSIGNED, SIGNED或STD_LOGIC的操作數(shù)p轉(zhuǎn)換成位寬為b的STD_LOGIC_VECTOR類型的數(shù)據(jù)。
二、運(yùn)算操作符和屬性
1.運(yùn)算操作符
l賦值運(yùn)算符
賦值運(yùn)算符用來給信號(hào)、變量和常數(shù)賦值。
<=用于對(duì)SIGNAL類型賦值;
:=用于對(duì)VARIABLE,CONSTANT和GENERIC賦值,也可用于賦初始值;
=>用于對(duì)矢量中的某些位賦值,或?qū)δ承┪恢獾钠渌毁x值(常用OTHERS表示)。
例:
SIGNAL x: STD_LOGIC;
VARIABLE y: STD_LOGIC_VECTOR(3 DOWNTO 0);–最左邊的位是MSB
SIGNAL w: STD_LOGIC_VECTOR(0 TO 7);–最右邊的位是MSB
x <= ‘1’;
y := “0000”;
w <= “1000_0000”;– LSB位為1,其余位為0
w <= (0 => ‘1’, OTHERS => ‘0’);– LSB位是1, 其他位是0
l邏輯運(yùn)算符
操作數(shù)必須是BIT, STD_LOGIC或STD_ULOGIC類型的數(shù)據(jù)或者是這些數(shù)據(jù)類型的擴(kuò)展,即BIT_VECTOR, STD_LOGIC_VECTOR,STD_ULOGIC_VECTOR。
VHDL的邏輯運(yùn)算符有以下幾種:(優(yōu)先級(jí)遞減)
?NOT —— 取反
?AND —— 與
?OR —— 或
?NAND —— 與非
?NOR —— 或非
?XOR —— 異或
l算術(shù)運(yùn)算符
操作數(shù)可以是INTEGER, SIGNED, UNSIGNED, 如果聲明了std_logic_signed或std_logic_unsigned,可對(duì)STD_LOGIC_VECTOR類型的數(shù)據(jù)進(jìn)行加法或減法運(yùn)算。
+ —— 加
-—— 減
* —— 乘
/ —— 除
** —— 指數(shù)運(yùn)算
MOD —— 取模
REM —— 取余
ABS —— 取絕對(duì)值
加,減,乘是可以綜合成邏輯電路的;除法運(yùn)算只在除數(shù)為2的n次冪時(shí)才能綜合,此時(shí)相當(dāng)于對(duì)被除數(shù)右移n位;對(duì)于指數(shù)運(yùn)算,只有當(dāng)?shù)讛?shù)和指數(shù)都是靜態(tài)數(shù)值(常量或GENERIC參數(shù))時(shí)才是可綜合的;對(duì)于MOD運(yùn)算,結(jié)果的符號(hào)同第二個(gè)參數(shù)的符號(hào)相同,對(duì)于REM運(yùn)算,結(jié)果的符號(hào)同第一個(gè)參數(shù)符號(hào)相同。
l關(guān)系運(yùn)算符
=, /=, <, >, <=, >=
左右兩邊操作數(shù)的類型必須相同。
l移位操作符
<左操作數(shù)> <移位操作符> <右操作數(shù)>
其中左操作數(shù)必須是BIT_VECTOR類型的,右操作數(shù)必須是INTEGER類型的(可以為正數(shù)或負(fù)數(shù))。
VHDL中移位操作符有以下幾種:
usll邏輯左移– 數(shù)據(jù)左移,右端補(bǔ)0;
usrl邏輯右移– 數(shù)據(jù)右移,左端補(bǔ)0;
usla算術(shù)左移– 數(shù)據(jù)左移,同時(shí)復(fù)制最右端的位,填充在右端空出的位置;
usra算術(shù)右移– 數(shù)據(jù)右移,同時(shí)復(fù)制最左端的位,填充在左端空出的位置;
urol循環(huán)邏輯左移 — 數(shù)據(jù)左移,從左端移出的位填充到右端空出的位置上;
uror循環(huán)邏輯右移 – 數(shù)據(jù)右移,從右端移出的位填充到左端空出的位置上。
例:x <= “01001”,那么:
y <= x sll 2;–邏輯左移2位,y<=”00100”
y <= x sla 2;–算術(shù)左移2位,y<=”00111”
y <= x srl 3;–邏輯右移3位,y<=”00001”
y <= x sra 3;–算術(shù)右移3位,y<=”00001”
y <= x rol 2;–循環(huán)左移2位,y<=”00101”
y <= x srl -2;–相當(dāng)于邏輯左移2位
l并置運(yùn)算符
用于位的拼接,操作數(shù)可以是支持邏輯運(yùn)算的任何數(shù)據(jù)類型。有以下兩種:
2&
2(, , , )
與Verilog中{}的功能一樣。
2.屬性(ATTRIBUTE)
l數(shù)值類屬性
數(shù)值類屬性用來得到數(shù)組、塊或一般數(shù)據(jù)的相關(guān)信息,例如可用來獲取數(shù)組的長度和數(shù)值范圍等。
以下是VHDL中預(yù)定義的可綜合的數(shù)值類屬性:
d’LOW–返回?cái)?shù)組索引的下限值
d’HIGH–返回?cái)?shù)組索引的上限值
d’LEFT–返回?cái)?shù)組索引的左邊界值
d’RIGHT–返回?cái)?shù)組索引的右邊界值
d’LENGTH–返回矢量的長度值
d’RANGE–返回矢量的位寬范圍
d’REVERSE_RANGE–按相反的次序返回矢量的位寬范圍
例:定義信號(hào) SIGNAL d: STD_LOGIC_VECTOR(7 DOWNTO 0);
則有:d’LOW = 0, d’HIGH = 7, d’LEFT = 7, d’RIGHT = 0, d’LENGTH = 8,d’RANGE = (7 DOWNTO 0), d’REVERSE_RANGE = (0 TO 7).
l信號(hào)類屬性
對(duì)于信號(hào)s,有以下預(yù)定義的屬性(可綜合的):
s’EVENT若s的值發(fā)生變化,則返回布爾量TRUE,否則返回FALSE
s’STABLE若s保持穩(wěn)定,則返回TRUE,否則返回FALSE
例:clk的上升沿判斷
IF (clk’EVENT AND clk = ‘1’)
IF (NOT clk’STABLE AND clk = ‘1’)
WAIT UNTIL (clk’EVENT AND clk = ‘1’)
3.通用屬性語句
GENERIC語句提供了一種指定常規(guī)參數(shù)的方法,所指定的參數(shù)是靜態(tài)的,增加了代碼的可重用性,類似于Verilog中的parameter與defparam。GENERIC語句必須在ENTITY中進(jìn)行聲明,由GENERIC語句指定的參數(shù)是全局的,不僅可在ENTITY內(nèi)部使用,也可在后面的整個(gè)設(shè)計(jì)中使用。語法結(jié)構(gòu)如下:
GENERIC (parameter_name: parameter_type := parameter_value);
用GENERIC語句指定多個(gè)參數(shù):
GENERIC (n: INTEGER := 8; vector: BIT_VECTOR := “0000_1111”);
三、并發(fā)代碼
VHDL中并發(fā)描述語句有WHEN和GENERATE。除此之外,僅包含AND, NOT, +, *和sll等邏輯、算術(shù)運(yùn)算操作符的賦值語句也是并發(fā)執(zhí)行的。在BLOCK中的代碼也是并發(fā)執(zhí)行的。
從本質(zhì)上講,VHDL代碼是并行執(zhí)行的。只有PROCESS, FUNCTION, PROCEDURE內(nèi)部的代碼才是順序執(zhí)行的。但是當(dāng)它們作為一個(gè)整體時(shí),與其他模塊之間又是并行執(zhí)行的。并發(fā)代碼稱為“數(shù)據(jù)流”代碼。
通常我們只能用并發(fā)描述語句來實(shí)現(xiàn)組合邏輯電路,為了實(shí)現(xiàn)時(shí)序邏輯電路,必須使用順序描述語句。事實(shí)上,使用順序描述語句可以同時(shí)實(shí)現(xiàn)組合邏輯電路和時(shí)序邏輯電路。
在并發(fā)代碼中可以使用以下各項(xiàng):
?運(yùn)算操作符
?WHEN語句(WHEN/ELSE或WITH/SELECT/WHEN)
?GENERATE語句
?BLOCK語句
使用運(yùn)算操作符
運(yùn)算類型
運(yùn)算操作符
操作數(shù)類型
邏輯運(yùn)算
NOT, AND, NAND,OR
NOR, XOR, XNORBIT, BIT_VECTOR, STD_LOGIC, STD_LOGIC_VECTOR
STD_ULOGIC, STD_ULOGIC_VECTOR
算術(shù)運(yùn)算符
+, —, *, /, **
INTEGER, SIGNED, UNSIGNED
比較運(yùn)算符
=, /=, <, >, <=, >=
任意數(shù)據(jù)類型
移位運(yùn)算符
sll, srl, sla, sra, rol, ror
BIT_VECTOR
并置運(yùn)算符
&,(, , ,)
STD_LOGIC, STD_LOGIC_VECTOR, STD_ULOGIC
STD_ULOGIC_VECTOR, SIGNED, UNSIGNED
WHEN語句
WHEN語句是一種基本的并發(fā)描述語句,有兩種形式:WHEN/ELSE和WITH/SELECT/WHEN。
WHEN/ELSE語法結(jié)構(gòu):
assignment WHEN condition ELSE
assignment WHEN condition ELSE
…;
WITH/SELECT/WHEN語法結(jié)構(gòu)
WITH identifier SELECT
assignment WHEN value,
assignemnt WHEN value,
…;
當(dāng)使用WITH/SELECT/WHEN時(shí),必須對(duì)所有可能出現(xiàn)的條件給予考慮,使用關(guān)鍵字OTHERS,如果在某些條件出現(xiàn)時(shí)不需要進(jìn)行任何操作,那應(yīng)該使用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;
對(duì)于WHEN語句,WHEN value的描述方式有以下幾種:
WHEN value–針對(duì)單個(gè)值進(jìn)行判斷
WHEN value1 to value2–針對(duì)取值范圍進(jìn)行判斷
WHEN value1 | value2 | …–針對(duì)多個(gè)值進(jìn)行判斷
GENERATE語句
GENERATE語句和順序描述語句中的LOOP語句一樣用于循環(huán)執(zhí)行某項(xiàng)操作,通常與FOR一起使用。語法結(jié)構(gòu)如下:
label: FOR identifier IN range GENERATE
(concurrent assignments)
END GENERATE
GENERATE語句還有另一種形式:IF/GENERATE,此處不允許使用ELSE。IF/GENERATE可以嵌套在FOR/GENERATE內(nèi)部使用。反之亦然。
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中循環(huán)操作的上界和下界必須是靜態(tài)的,在使用過程中還要注意多值驅(qū)動(dòng)問題。
例:
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。
nSimple BLOCK
Simple BLOCK僅僅是對(duì)原有代碼進(jìn)行區(qū)域分割,增強(qiáng)整個(gè)代碼的可讀性和可維護(hù)性。語法結(jié)構(gòu)如下:
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,其內(nèi)部都可以嵌套其他的BLOCK語句,相應(yīng)的語法結(jié)構(gòu)如下:
label1: BLOCK
[頂層BLOCK聲明部分]
BEGIN
[頂層BLOCK并發(fā)描述部分]
label2: BLOCK
[嵌套BLOCK聲明部分]
BEGIN
[嵌套BLOCK并發(fā)描述部分]
END BLOCK label2;
[頂層BLOCK其他并發(fā)描述語句]
END BLOCK label1;
———————————————————————————————————
nGuarded BLOCK
多了一個(gè)衛(wèi)式表達(dá)式,只有當(dāng)衛(wèi)式表達(dá)式為真時(shí)才能執(zhí)行。語法結(jié)構(gòu)如下:
Label: BLOCK(衛(wèi)式表達(dá)式)
[聲明部分]
BEGIN
(衛(wèi)式語句和其他并發(fā)描述語句)
END BLOCK label;
四、順序代碼
在PROCESS, FUNCTION, PROCEDURE內(nèi)部的代碼都是順序執(zhí)行的,這樣的語句包括IF,WAIT,CASE和LOOP。變量只能在順序代碼中使用,相對(duì)于信號(hào)而言,變量是局部的,所以它的值不能傳遞到PROCESS,F(xiàn)UNCTION和PROCEDURE的外部。
1.進(jìn)程(PROCESS)
進(jìn)程內(nèi)部經(jīng)常使用IF,WAIT,CASE或LOOP語句。PROCESS具有敏感信號(hào)列表(sensitivity list),或者使用WAIT語句進(jìn)行執(zhí)行條件的判斷。PROCESS必須包含在主代碼段中,當(dāng)敏感信號(hào)列表中的某個(gè)信號(hào)發(fā)生變化時(shí)(或者當(dāng)WAIT語句的條件得到滿足時(shí)),PROCESS內(nèi)部的代碼就順序執(zhí)行一次。語法結(jié)構(gòu)如下:
[label: ] PROCESS (sensitivity list)
[VARIABLE name type [range] [ := initial_value; ]]
BEGIN
(順序執(zhí)行的代碼)
END PROCESS [label];
如果要在PROCESS內(nèi)部使用變量,則必須在關(guān)鍵字BEGIN之前的變量聲明部分對(duì)其進(jìn)行定義。變量的初始值是不可綜合的,只用于仿真。在設(shè)計(jì)同步電路時(shí),要對(duì)某些信號(hào)邊沿的跳變進(jìn)行監(jiān)視(時(shí)鐘的上升沿或下降沿)。通常使用EVENT屬性來監(jiān)視一個(gè)信號(hào)是否發(fā)生了變化。
2.信號(hào)和變量
信號(hào)可在PACKAGE,ENTITY和ARCHITECTURE中聲明,而變量只能在一段順序描述代碼的內(nèi)部聲明。因此,信號(hào)通常是全局的,變量通常是局部的。賦予變量的值是立刻生效的,在后續(xù)的代碼中,此變量將使用新的變量值,而信號(hào)的值通常只有在整個(gè)PROCESS執(zhí)行完畢后才開始生效。
3.IF語句
IF/ELSE語句在綜合時(shí)可能會(huì)產(chǎn)生不必要的優(yōu)先級(jí)解碼電路。IF語句語法結(jié)構(gòu)如下:
IF conditions THEN assignments;
ELSIF conditions THEN assignments;
ELSE assignments;
END IF;
————————————————————————————————
例:
IF (x < y) temp := “1111_1111”;
ELSIF (x = y AND w = ‘0’) THEN temp := “1111_0000”;
ELSE temp := (OTHERS => ‘0’);
4.WAIT語句
如果在process中使用了WAIT語句,就不能使用敏感信號(hào)列表了。WAIT語句使用以下3種形式的語法結(jié)構(gòu):
WAIT UNTIL signal_condition;
WAIT ON signal1 [, signal2, ...];
WAIT FOR time;
WAIT UNTIL后面只有一個(gè)信號(hào)條件表達(dá)式,更適合于實(shí)現(xiàn)同步電路(將時(shí)鐘的上升沿或下降沿作為條件),由于沒有敏感信號(hào)列表,所以它必須是process的第一條語句。當(dāng)WAIT UNTIL語句的條件滿足是,process內(nèi)部的代碼就執(zhí)行一遍。
–帶有同步復(fù)位的8bit寄存器
process–沒有敏感信號(hào)列表
begin
wait until (clk’event and clk = ‘1′);
if (rst = ‘1′) then
output <= (others => ‘0′);
elsif (clk’event and clk = ‘1′) then
output <= input;
end if;
end process;
WAIT ON 語句中可以出現(xiàn)多個(gè)信號(hào),只要信號(hào)列表中的任何一個(gè)發(fā)生變化,process內(nèi)的代碼就開始執(zhí)行。
–帶異步復(fù)位的8bit寄存器
process
begin
wait on clk, rst;
if (rst = ‘1′) then
output <= (others => ‘0′);
elsif (clk’event and clk = ‘1′) then
output <= input;
end if;
end process;
WAIT FOR 語句只能用于仿真。
5.CASE 語句
CASE語句的語法結(jié)構(gòu)如下:
CASE表達(dá)式IS
WHEN條件表達(dá)式=>順序執(zhí)行語句;
WHEN條件表達(dá)式=>順序執(zhí)行語句;
……
END CASE
例:
case control is
when “00″=>x <= a; y <= b;
when “01″=>x <= b; y <= c;
when others =>x <= “0000″; y <= “zzzz”;
end case;
關(guān)鍵詞OTHERS代表了所有未列出的可能情況,與Verilog中default相當(dāng)。關(guān)鍵詞NULL表示沒有操作發(fā)生,如WHEN OTHERS => NULL.
CASE語句允許在每個(gè)測(cè)試條件下執(zhí)行多個(gè)賦值操作,WHEN語句只允許執(zhí)行一個(gè)賦值操作。
6.LOOP語句
LOOP語句用在需要多次重復(fù)執(zhí)行時(shí)。語法結(jié)構(gòu)有以下幾種:
FOR/LOOP: 循環(huán)固定次數(shù)
[label: ] FOR循環(huán)變量IN范圍LOOP
(順序描述語句)
END LOOP [label];
WHILE/LOOP: 循環(huán)執(zhí)行直到某個(gè)條件不再滿足
[label: ] WHILE condition LOOP
(順序描述語句)
END LOOP [label];
EXIT: 結(jié)束整個(gè)循環(huán)操作
[label: ] EXIT[label] [WHEN condition];
NEXT: 跳出本次循環(huán)
[label: ] NEXT [loop_label] [WHEN condition];
Example: FOR/LOOP
for i in 0 to 5 loop
x(i) <= enable and w(i+2);
y(0, i) <= w(i);
end loop
Example: WHILE/LOOP
while (i < 10) loop — 0~9
wait until clk’event and clk = ‘1′;
(其他語句)
end loop;
for i in 0 to data’range loop
case data(i) is
when ‘0′ =>count := count + 1;
when others => null;
end case;
end loop;
7.CASE語句和IF語句的比較
IF語句和CASE語句編寫的代碼在綜合、優(yōu)化后最終生成的電路結(jié)構(gòu)是一樣的。
例:下面兩段代碼綜合后可以得到結(jié)構(gòu)相同的多路復(fù)用器
————with IF————–
if(sel = “00″)then x <= a;
elsif (sel = “01″)then x <= b;
elsif (sel = “10″)then x <= c;
else x <= d;
end if;
————-with case———–
case sel is
when “00″ =>x <= a;
when “01″ =>x <= b;
when “10″ =>x <= c;
when others =>x <= d;
end case;
8.CASE語句和WHEN語句的比較
case語句和when語句的不同之處在于,when語句是并發(fā)執(zhí)行的,case語句是順序?qū)嵭械?/b>。
–下面兩段代碼的功能等效
——-with when——————
with sel select
x <= a when “000″,
b when “001″,
c when “101″,
unaffected when others;
——-with case——————
case sel is
when “000″ => x <= a;
when “001″ => x <= b;
when “101″ => x <= c;
when others => null;
end case;
9.使用順序代碼設(shè)計(jì)組合邏輯電路
原則1:確保在process中用到的所有輸入信號(hào)都出現(xiàn)在敏感信號(hào)列表中;
原則2:電路的真值表必須在代碼中完整的反映出來。(否則會(huì)生成鎖存器)
五、信號(hào)和變量
常量和信號(hào)是全局的,既可以用在順序執(zhí)行的代碼中,也可用在并發(fā)執(zhí)行的代碼中。變量是局部的,只能用在順序代碼中,并且它們的值是不能直接向外傳遞的。
1.常量
CONSTANT name: type := value;
2.信號(hào)-signal
VHDL中的signal代表的是邏輯電路中的“硬”連線,既可用于電路的輸入/輸出端口,也可用于電路內(nèi)部各單元之間的連接。Entity的所有端口默認(rèn)為signal。格式如下:
SIGNAL name: type [range] [:= initial value];
當(dāng)信號(hào)用在順序描述語句中時(shí),其值不是立刻更新的,信號(hào)值是在相應(yīng)的進(jìn)程、函數(shù)或過程完成之后才進(jìn)行更新的。對(duì)信號(hào)賦初值的操作時(shí)不可綜合的。
3.變量
變量僅用于局部電路的描述,只能在順序執(zhí)行的代碼中使用,而且對(duì)它的賦值是立即生效的,所以新的值可在下一行代碼中立即使用。格式:
VARIABLE name: type [range] [:= initial value];
對(duì)變量的賦初值操作也是不可綜合的。
4.寄存器的數(shù)量
當(dāng)一個(gè)信號(hào)的賦值是以另一個(gè)信號(hào)的跳變?yōu)闂l件時(shí),或者說當(dāng)發(fā)生同步賦值時(shí),該信號(hào)經(jīng)過編譯后就會(huì)生成寄存器。如果一個(gè)變量是在一個(gè)信號(hào)跳變時(shí)被賦值的,并且該值最終又被賦給了另外的信號(hào),則綜合后就會(huì)生成寄存器。如果一個(gè)信號(hào)在還沒有進(jìn)行賦值操作時(shí)已被使用,那么也會(huì)在綜合時(shí)生成寄存器。
process (clk)
begin
if (clk’event and clk = ‘1′) then
output1 <= temp;– output1被寄存
output2 <= a;– output2被寄存
end if;
end process;
process (clk)
begin
if (clk’event and clk = ‘1′) then
output1 <= temp;– output1被寄存
end if;
output2 <= a;– output2未被寄存
end process;
process (clk)
variable temp:bit;
begin
if (clk’event and clk = ‘1′) then
temp <= a;
end if;
x <= temp;– temp促使x被寄存
end process;
六、包集元件
1.包集
經(jīng)常使用的代碼通常以component,function或procedure的形式編寫。這些代碼被添加到package中,并在最后編譯到目標(biāo)library中。Package中還可以包含TYPE和CONSTANT的定義。語法格式如下:
package package_name is
(declaration)
end package_name;
package body package_name is
(function and procedure description)
end package_name;]
Example6.1 簡單的程序包
library ieee;
use ieee.std_logic_1164.all;
———————————————————————-
package my_package is
type state is (st1, st2, st3, st4);
type color is (red, green, blue);
constant vec:std_logic_vector(7 downto0) := “1111_1111″;
end my_package;
Example6.2 內(nèi)部包含函數(shù)的package
library ieee;
use ieee.std_logic_1164.all;
———————————————————————-
package my_package is
type state is (st1, st2, st3, st4);
type color is (red, green, blue);
contant vec: std_logic_vector(7 downto 0) := “1111_1111″;
function positive_edge(signal s: std_logic) return boolean;
end my_package;
———————————————————————-
package body my_package is
function positive_edge(signal s: std_logic) return booleanis
begin
return(s’event and s = ‘1′);
end positive_edge;
end my_package;