VHDL語法簡單總結(jié)

一個(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)如下:

labelBLOCK

[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í)行的,這樣的語句包括IFWAITCASELOOP。變量只能在順序代碼中使用,相對(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)可在PACKAGEENTITYARCHITECTURE中聲明,而變量只能在一段順序描述代碼的內(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;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評(píng)論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,570評(píng)論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評(píng)論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評(píng)論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,786評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,219評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,438評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,971評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,796評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,995評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,230評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評(píng)論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,697評(píng)論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,991評(píng)論 2 374

推薦閱讀更多精彩內(nèi)容