EDA技術和VHDL設計第4章VHDL語言要素課件_第1頁
EDA技術和VHDL設計第4章VHDL語言要素課件_第2頁
EDA技術和VHDL設計第4章VHDL語言要素課件_第3頁
EDA技術和VHDL設計第4章VHDL語言要素課件_第4頁
EDA技術和VHDL設計第4章VHDL語言要素課件_第5頁
已閱讀5頁,還剩283頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第4章VHDL語言要素

4.1VHDL文字規(guī)則4.2數據對象4.3VHDL的數據類型4.4VHDL操作符4.5屬性第4章VHDL語言要素

4.1VHDL文字規(guī)則4.1VHDL文字規(guī)則

VHDL文字主要包括數值型文字和標識符。數值型文字主要有數字型、字符串型。

4.1.1數值型文字

1.數字型

數字型文字有多種表達方式,列舉如下:

(1)整數(Integer)。整數是十進制數,與算數整數相似,包括正整數、負整數和零,表示范圍是?-(231?-?1)~(231?-?1),即?-2?147?483?647~2?147?483?647。整數的表達方式舉例:

1,234,567E2(=?56700),12_345_678(?=?12?345?678)4.1VHDL文字規(guī)則

VHDL文字主要包括其中,數字間的下劃線僅僅是為了提高文字的可讀性,相當于一個空的間隔符,沒有其他意義,也不影響文字本身的數值。

(2)實數(Real)。實數也是十進制的數,但必須帶有小數點。它類似于數學上的實數,或稱浮點數,表示范圍是?-1.0E38~1.0E38。實數的表達方式舉例:

0.0,123.45,6.0,78.99E?-?2(?=?0.7899),12_345.678_999(=12345.678999)其中,數字間的下劃線僅僅是為了提高文字的可讀性,相當于一個空(3)以數制基數表示的格式。用這種方式表示的數由五部分組成:第一部分,基數,用十進制數表明所用數制;第二部分,數制隔離符號“#”;第三部分,所要表達的數;第四部分,指數隔離符號“#”;第五部分,用十進制數表示的指數,如果這一部分為0可以省去不寫。以數制基數表示的文字表達方式舉例:

10#235# (十進制數表示,等于235)

2#1110_1011# (二進制數表示,等于235)

8#353# (八進制數表示,等于235)

16#EB# (十六進制數表示,等于235)

16#E#E1 (十六進制數表示,等于16#E0#,等于2#11100000#,等于224)

16#F.01#E2 (十六進制數表示,等于16#F01#,等于3841.00)(3)以數制基數表示的格式。用這種方式表示的數由五部分(4)物理文字量。物理文字量包括時間、電阻、電流等,但此類文字綜合器不能接受,多用于仿真。物理文字量的表達方式舉例:

55ns,177A,23m

它一般由整數和單位兩部分組成,整數與單位間至少留一個空格。(4)物理文字量。物理文字量包括時間、電阻、電流等,但2.字符串型

字符是用單引號引起來的ASCII字符,可以是數值,也可以是符號或字母,如?‘A’、‘8’、‘a’、‘-’。字符串是字符的一維數組,必須使用雙引號引起來。VHDL中有兩種字符串:文字字符串和數位字符串。

(1)文字字符串。文字字符串即用雙引號引起來的一串文字,舉例:

“STRING”,“BothAandBequalto0“

(2)數位字符串。數位字符串即位矢量,用雙引號引起來的一維位(BIT,VHDL預定義數據類型)數據,采用基數符加字符串的表達形式,舉例:2.字符串型

字符是用單引號引起來的ASCII字符B“1_1101_0010” (二進制數組,位矢量長度是9)

O“34” (八進制數組,位矢量長度是6,相當于B“011100”)

X“1AB” (十六進制數組,位矢量長度是12)

其中,B代表二進制基數符號,表示二進制數位0或者1,字符串中的每一位表示一個BIT;O代表八進制基數符號,字符串中的每一位代表一個八進制數,即3位BIT的二進制數;X代表十六進制基數符號,字符串中的每一位代表一個十六進制數,即一個4位的二進制數。B“1_1101_0010” (二進制數組,位矢量長度是分析下面表達方式的正確性:

B“1000_1110”--二進制數組,數組長度8,表達正確

B“10001110” --二進制數組,數組長度8,表達正確

“1000_1110” --表達錯誤,如果省去B,則不能加下劃線

“10001110” --表達正確

"1AB" --表述錯誤,除二進制外,八進制和十六進制不能省去基數符分析下面表達方式的正確性:

B“1000_1114.1.2標識符

VHDL中的標識符可以是常量、變量、信號、端口、子程序或參數的名稱。使用標識符要遵守一定的法則,這不僅是對電子系統(tǒng)設計工程師的一個約束,同時也為各種EDA工具提供標準的書寫規(guī)范,使之在綜合仿真過程中不產生歧義,易于仿真。VHDL中的標識符分為基本標識符和擴展標識符兩種?;緲俗R符的規(guī)則如下:

(1)標識符由字母(A~Z,a~z)、數字(0~9)和下劃線(?_?)組成。

(2)任何標識符必須以英文字母開頭。4.1.2標識符

VHDL中的標識符可以是常量、變量(3)不允許出現多個連續(xù)的下劃線,只能是單一下劃線,且不能以下劃線結束。

(4)標識符不區(qū)分英文字母大小寫。

(5)?VHDL定義的保留字或關鍵詞,不能用作標識符。

(6)?VHDL中的注釋文字一律由兩個連續(xù)的連接線“--”開始,可以出現在任一語句后面,也可以出現在獨立行。

分析下面標識符的合法性:

_decoder --非法標識符,起始不能是非英文字母

3dop --非法標識符,起始不能是非英文字母

large#number –非法標識符,“?!辈荒艹蔀闃俗R符的構成(3)不允許出現多個連續(xù)的下劃線,只能是單一下劃線,且sig_N --合法標識符

state0 --合法標識符

NOT-ACK --非法標識符,“-”不能成為標識符的構成

Data__bus --非法標識符,不能含有多個下劃線

Copper__ --非法標識符,不能以下劃線結束

Return --非法標識符,關鍵字不能用作標識符

tx_clk --合法標識符sig_N --合法標識符

staVHDL93標準還支持擴展標識符,以反斜杠來界定,免去了87標準中基本標識符的一些限制,如:可以以數字打頭,允許包含圖形符號,允許使用VHDL保留字,區(qū)分字母大小寫等。擴展標識符舉例:\entity\、\2chip\、\EDA\、\eda\、\aa\\bb\。但目前仍有較多VHDL工具不支持擴展標識符,所以本書仍以87標準為準。由于VHDL語言不區(qū)分大小寫,在書寫時一定要養(yǎng)成良好的書寫習慣。一般而言,應用關鍵詞時應大寫,自行定義的標識符應小寫。VHDL93標準還支持擴展標識符,以反斜杠來界定,免去了4.2數據對象

在VHDL中,凡是可以賦予一個值的客體稱為數據對象。數據對象是數據類型的載體,可以把它看做一個容器,能夠接收不同數據類型的賦值。常用的數據對象有:常量(CONSTANT)、變量(VARIABLE)和信號(SIGNAL)。4.2數據對象

在VHDL中,凡是4.2.1常量

常量是指在設計描述中不會變化的值。常量的使用主要是為了使代碼更容易閱讀和修改。在VHDL描述中,一般用常量名代替數值。常量是一個恒定不變的值,一旦作了數據類型和賦值定義后,在代碼中就不能再改變,因而具有全局意義。常量聲明的格式如下:

CONSTANT常量名:數據類型:=取值;4.2.1常量

常量是指在設計描述中不會變化的值。?!纠?-1】

CONSTANTwidth_s :INTEGER:=8; --聲明常量width_s,數據類型為整型,值為8

CONSTANTdelay :TIME:=25ns; --聲明常量dealy作為延時時間25ns

CONSTANTfbus :BIT_VECTOR:=“010100”;--聲明常量fbus為位矢量類型

常量的使用注意以下幾個要點:

(1)常量的賦值必須符合聲明的數據類型。

(2)常量一旦賦值就不能再改變。若要改變常量值,必須要改變設計,改變常量的聲明?!纠?-1】

CONSTANTwidth_s (3)常量聲明所允許的范圍有實體、結構體、進程、子程序、塊和程序包。

(4)常量具有可視性規(guī)則,即常量的聲明位置決定它的使用范圍。如果常量是在程序包中聲明的,則調用此程序包的所有設計實體都可以使用,此時具有最大的全局化特征;常量如果聲明在設計實體中,則這個實體定義的所有結構體都可以使用;常量如果聲明在結構體內,則只能用于該結構體;如果聲明在某進程中,則只能在該進程中使用。(3)常量聲明所允許的范圍有實體、結構體、進程、子程序4.2.2變量

變量用于對數據的暫時存儲。變量是一個局部量,只能在進程和子程序中使用。變量聲明的格式如下:

VARIABLE變量名:數據類型[:=初始值];

【例4-2】

VARIABLEcount:INTEGERRANGE0TO99:=0;--聲明變量count,數據類型為整型,初值為0

VARIABLEresult:STD_LOGIC:='1'; --變量result為標準邏輯位數據類型,初值為‘1’

VARIABLEx,y,z:STD_LOGIC_VECTOR(7DOWNTO0);--聲明變量x、y、z為標準邏輯矢量數據類型,沒有定義初值4.2.2變量

變量用于對數據的暫時存儲。變量是一個雖然變量可以在聲明時賦予初始值,但綜合器并不支持初始值的設置,使用時將忽略。初始值僅對仿真器有效。當變量在聲明語句中沒有賦予初值時,可以通過變量賦值語句在使用時對其賦值。變量賦值語句的格式如下:

目標變量名:=表達式;雖然變量可以在聲明時賦予初始值,但綜合器并不支持初始值的【例4-3】

VARIABLEx,y,z:STD_LOGIC_VECTOR(7DOWNTO0);--聲明變量x、y、z

x:=“01001010”;

y:=“00010001”;

z:=x(0TO3)&y(4TO7);

需要注意的是,賦值語句中的表達式必須與目標變量具有相同的數據類型。變量在使用時還需注意以下幾個要點:

(1)變量是一個局部量,只用于進程和子程序。變量不能將信息帶出對它作定義的設計單元。

(2)變量的賦值是立即發(fā)生的,不存在任何延時的行為?!纠?-3】

VARIABLEx,y,z:ST(3)?VHDL語言規(guī)則不支持變量附加延時語句。

(4)變量常用在實現某種運算的賦值語句中。變量賦值和初始化賦值都使用符號“:=”。

(5)變量不能用于硬件連線。

在VHDL93標準中對變量的類型作了增加,引入了全程變量,可以把值傳送到進程外部,參見例4-4。從分析可知,定義了一個全程變量v,用于在進程P0和P1間傳遞信息。需要注意的是,全程變量也不能作為進程的敏感參數,并且可能導致一些不確定性,使用全程變量必須小心。(3)?VHDL語言規(guī)則不支持變量附加延時語句。

【例4-4】【例4-4】4.2.3信號

信號是電路內部硬件實體相互連接的抽象表示,可以實現進程之間的通信。信號聲明的格式如下:

SIGNAL信號名:數據類型[:=初始值];

【例4-5】

SIGNALsys_clk :BIT:=‘0’; --聲明位型的信號sys_clk,初始值為低電平

SIGNALtemp :STD_LOGIC_VECTOR(7DOWNTO0);--信號temp,數據類型為標準邏輯矢量,沒有設置初始值

SIGNALs1,s2 :STD_LOGIC; --聲明了兩個STD_LOGIC類型的信號s1和s24.2.3信號

信號是電路內部硬件實體相互連接的抽象與變量相同,對信號初始值的設置也不是必須的,并且僅在仿真中有效。一般在設計中對信號進行賦值,信號賦值語句的格式如下:

目標信號名<=表達式;

【例4-6】

SIGNALa,b,c,d:STD_LOGIC_VECTOR(7DOWNTO0);

a<=“10101010”; --以二進制形式將8個比特一次賦值完畢

b<=X“AA”; --以十六進制形式賦值,在VHDL97標準中定義

c(7DOWNTO4)<=“1100”; --比特分割,信號c的高4位被賦值“1100”

d(7)<='1'; --單比特賦值與變量相同,對信號初始值的設置也不是必須的,并且僅在仿真信號的使用需要注意以下幾個要點:

(1)信號的聲明范圍是程序包、實體和結構體。信號不能在進程和子程序中聲明,但可以使用。

(2)與常量相似,信號也具有可視性規(guī)則。在程序包中聲明的信號,對于所有調用此程序包的設計實體都可見;在實體中聲明的信號,在其對應的所有結構體中都可見;在結構體中聲明的信號,此結構體內部都可見。

(3)實體中定義的輸入、輸出端口也是信號,只是附加了數據流動的方向。信號的使用需要注意以下幾個要點:

(1)信號的聲明(4)符號“:=”用于對信號賦初始值,符號“<=”用于信號的代入賦值。代入賦值可以設置延時,如:a<=“10101010”AFTER5ns。

(5)信號包括I/O引腳信號和IC內部緩沖信號,有硬件電路與之對應,所以即使沒有設置延時,信號之間的傳遞也有實際的附加延時。

(6)信號能夠實現進程間的通信,即把進程外的信息帶入進程內部,把進程內部的信息帶出進程。所以,信號能夠列入進程的敏感列表,而變量不能列入。(4)符號“:=”用于對信號賦初始值,符號“<=”用于(7)信號的賦值可以出現在進程中,也可以直接出現在結構體的并行語句中,但它們的運行含義不同。前者屬于順序信號賦值,允許同一信號有多個驅動源(賦值源),但只有最后的賦值語句進行有效的賦值操作,如例4-7中的y被賦值為c;后者屬于并行信號賦值,賦值操作是各自獨立并行發(fā)生的,不允許對同一信號多次賦值,如例4-8中的y被賦值為a+b,z被賦值為c,不允許對y多次賦值。同樣地,也不允許在不同的進程中對同一信號進行賦值操作。(7)信號的賦值可以出現在進程中,也可以直接出現在結構【例4-7】

ARCHITECTUREbhvOFadderIS

SIGNALa,b,c,y,z:INTEGER;

BEGIN

PROCESS(a,b,c)

BEGIN

y<=a+b;

y<=c;

ENDPROCESS;

ENDbhv;【例4-7】【例4-8】

ARCHITECTUREbhvOFadderIS

SIGNALa,b,c,y,z:INTEGER;

BEGIN

y<=a+b;

z<=c;

ENDbhv;【例4-8】

ARCHITECTUREbhvOF(8)在使用信號賦值語句時,可以一個信號定義幾個值,見例4-9。這些值應一一枚舉,中間使用逗號分開,AFTER后的延時值必須為升序。但需要特別注意的是,綜合工具不支持這種描述方法,該描述更多地使用在仿真測試中。更多的例子可以參見第8章。

【例4-9】時刻輸出信號c值

c<=‘0’, 0 ‘0’

‘1’AFTER5ns, 5 ‘1’

aAFTER10ns, 10 a

bAFTER15ns; 15b(8)在使用信號賦值語句時,可以一個信號定義幾個值,見4.2.4變量與信號的比較

在VHDL語言中,變量和信號是常用的數據對象,在形式上非常相似,但本質上卻有很大的差別。

變量賦值語句用來給變量賦值或改變變量值,使用賦值符號“:=”,且只能在VHDL的順序語句部分(進程和子程序)聲明和使用。當給變量賦值時,賦值操作立即執(zhí)行,該變量一直保留所賦值,直到下次賦值操作發(fā)生為止。變量一般用作局部數據的臨時存儲單元。4.2.4變量與信號的比較

在VHDL語言中,變量和信號賦值語句可以改變當前進程中信號的驅動值,使用賦值符號“<=”。信號只能在VHDL并行語句部分聲明,但既可以用在并行語句部分,也可以用在順序語句部分。當給信號賦值時,賦值操作并沒有立即生效,必須要等待一個延時,在每個進程結束時才完成賦值。信號一般用作電路單元的互聯。

當然,變量類型和信號類型如果完全一致,數據類型也完全相同,允許二者相互賦值。

例4-10和例4-11顯示了信號和變量在進程中賦值的區(qū)別。由于實體定義部分完全與例4-10相同,所以例4-11只顯示了結構體部分。兩個例子的區(qū)別僅在于例4-10使用的是信號a和b,而例4-11使用的是變量a和b。信號賦值語句可以改變當前進程中信號的驅動值,使用賦值符號【例4-10】【例4-10】EDA技術和VHDL設計第4章VHDL語言要素課件【例4-11】【例4-11】圖4-1和圖4-2分別是例4-10和例4-11綜合后的RTL電路圖,可以看出其結果有了較大的差別,這是由信號和變量不同的賦值特性所引起的。變量的賦值是立即執(zhí)行沒有延時的,所以a:=x和b:=a這兩條語句能夠立即執(zhí)行。圖4-1和圖4-2分別是例4-10和例4-11綜合后的R圖4-1例4-10的RTL電路圖圖4-1例4-10的RTL電路圖圖4-2例4-11的RTL電路圖圖4-2例4-11的RTL電路圖信號的賦值是有延時的,當進程啟動后,進程有固定的運行時間δ,在進程內的語句是順序執(zhí)行的。所有進程內的信號賦值語句均順序啟動各自的延時δ定時器(順序啟動的間隔幾乎為0),準備在定時結束后執(zhí)行賦值操作。可以發(fā)現,只有執(zhí)行到ENDPROCESS語句時,δ延時才結束,模擬器的時鐘才能向前推進。因此,進程中所有信號的賦值操作幾乎是在同時完成賦值的。所以,對于例4-9來說(仿真結果見圖4-3),當第2個時鐘上升沿到來后,啟動一次進程,信號a能夠在延時δ后獲得新的輸入信號x的值1,信號b也能在延時δ后完成賦值語句b<=a-1操作,但此時對賦值語句b而言,a值仍然是原有的a值0,而不是新的a值1,這是因為新的a值是基本與b的賦值同時完成得到的,所以完成賦值操作后b值仍然為-1。同樣地,對于輸出信號y,也在延時δ后完成賦值語句y<=b-2,得到y(tǒng)值為?-3。對于兩個例子賦值更新的數據可參見圖4-3和圖4-4??梢钥吹?,采用信號的例4-10比采用變量的例4-11慢了兩個時鐘周期,與RTL電路圖的結構相符。信號的賦值是有延時的,當進程啟動后,進程有固定的運行時間圖4-3例4-10的波形仿真結果圖4-3例4-10的波形仿真結果圖4-4例4-11的波形仿真結果圖4-4例4-11的波形仿真結果分析例4-12代碼片段,說明信號s_v的最后賦值結果。

從例4-12的注釋中可以看出,由于變量是立即賦值的,所以s_v(0)和s_v(1)得到了變量x和y第一次賦值,為“1”,隨后變量x和y進行了第二次賦值,并將值傳遞給了s_v(4)和s_v(5),使得s_v(4)和s_v(5)為“0”。雖然信號s1和s2也分別有兩次賦值操作,但按照在同一進程中執(zhí)行最后一條賦值語句的規(guī)則,s1和s2的值都是“0”,所以s_v(2)、s_v(3)、s_v(6)、s_v(7)均為“0”。所以完成賦值后,信號s_v應等于“00000011”。分析例4-12代碼片段,說明信號s_v的最后賦值結果。

【例4-12】【例4-12】EDA技術和VHDL設計第4章VHDL語言要素課件為便于讀者分析,下面再列舉兩個實例進行比較。

例4-13和例4-14的目的是完成一個移位寄存器,例4-14的實體部分與例4-13相同,這里略去。比較兩個例子,可以發(fā)現信號和變量的基本區(qū)別:聲明、使用的范圍不同。這也是例4-14中的語句“q<=reg”必須放在進程內的原因。觀察兩個例子的仿真結果,例4-13仿真結果正確,在第一個時鐘上升沿到來時,置入數據“10010010”,然后從第2個時鐘上升沿開始,每經過一次時鐘的上升沿,數據從低位向高位移位一次,最低位移入“1”。例4-14的仿真結果不正確,究其原因是因為變量立即賦值的特性。從例4-14的L10行可知,先進行reg(0)的賦值,再進行移位操作,這樣就使得移位時的reg(0)已經是得到賦值“1”后的新值了??梢钥闯觯盘栙x值的書寫順序不影響最后的結果;而變量由于具有立即賦值的特性,賦值的書寫順序就十分重要。當然,可以通過更改兩條賦值語句的前后順序來更正例4-14。為便于讀者分析,下面再列舉兩個實例進行比較。

例4-例4-13和例4-14都使用了IF語句的嵌套。IF語句首先判斷是否有時鐘信號clk的上升沿到來(例4-13中的L16),如有,則執(zhí)行嵌套在內的IF語句(例4-13中的L17~L19),判斷控制置數信號ctl是否為高電平“1”。這意味著,賦值語句“reg<=d”執(zhí)行的條件是時鐘信號clk的上升沿到來和信號ctl取值為“1”同時成立;而L18的兩條賦值語句執(zhí)行的條件是clk上升沿到來,但信號ctl取值為“0”。IF語句的嵌套在使用時應注意ENDIF結束句要與嵌入的條件句數量一致;且為方便代碼的閱讀和理解,每一層嵌套的IF語句相比于高一層次,應有縮進。

例4-13和例4-14的仿真波形圖如圖4-5和圖4-6所示。例4-13和例4-14都使用了IF語句的嵌套。IF語句首【例4-13】【例4-13】EDA技術和VHDL設計第4章VHDL語言要素課件【例4-14】【例4-14】圖4-5例4-13仿真波形結果圖4-5例4-13仿真波形結果圖4-6例4-14仿真波形結果圖4-6例4-14仿真波形結果

4.3VHDL的數據類型

VHDL是硬件設計語言,是一種類型概念很強的語言。任何的數據對象、函數或參數在聲明時必須要聲明數據類型,并且只能攜帶或返回該類型的值。不同的數據類型之間不能相互傳遞和作用。數據類型一般可以分為兩大類:可以從現成程序包中隨時獲得的預定義數據類型和用戶自定義數據類型。預定義數據類型在standard、std_logic_1164、std_logic_arith等多個程序包中定義。用戶自定義數據類型,其基本元素一般仍然是VHDL的預定義數據類型。需要注意的是,VHDL的綜合器并不支持所有的預定義數據類型和用戶自定義數據類型,如TIME、FILE、REAL等,但仿真器支持所有的數據類型。4.3VHDL的數據類型

VHDL是4.3.1預定義數據類型

1.VHDL預定義數據類型

VHDL標準程序包standard中定義了VHDL的基本數據類型,包括布爾(BOOLEAN)數據類型、位(BIT)數據類型、位矢量(BIT_VECTOR)數據類型、字符(CHARACTER)數據類型、字符串(STRING)數據類型、整數(INTEGER)數據類型、自然數(NATURAL)數據類型、正整數(POSITIVE)數據類型、實數(REAL)數據類型和時間(TIME)數據類型等。standard程序包屬于STD庫中的預編譯程序包,STD庫符合VHDL標準,在使用時已自動包含VHDL的源文件,因而不需要通過USE語句顯示調用。具體程序包定義參見附錄A。也可以通過打開QuartusⅡ軟件將其調出,選擇File→Open菜單,在軟件安裝目錄下選擇quartus/libraries/vhdl即可看到不同庫中的程序包。4.3.1預定義數據類型

1.VHDL預定義數據類(1)?BOOLEAN數據類型。布爾數據類型是一個二值枚舉型數據類型,它的取值只有TURE和FALSE兩種。綜合器使用一位二進制數表示BOOLEAN型的變量或信號。一般而言,綜合器將TRUE翻譯為1,FALSE翻譯為0。布爾型不屬于數值,不能用于計算,只能通過關系運算符獲得。

【例4-15】

IFa>bTHENy<=a;

ELSEy<=b;

ENDIF;

當a>b成立時,關系運算表達式的結果是布爾量TRUE,執(zhí)行y<=a;反之為FALSE,執(zhí)行y<=b。(1)?BOOLEAN數據類型。布爾數據類型是一個二值(2)?BIT數據類型。位數據類型也是一個二值的枚舉數據類型,取值只能是“1”或者“0”。位數據類型的數據對象,可以參與邏輯運算,結果仍然是位數據類型。VHDL綜合器使用一位二進制數表示位數據類型,如:

SIGNALs1:BIT:=‘1’;

SIGNALs2:BIT:=‘0’;

(3)?BIT_VECTOR數據類型。位矢量是基于位數據類型的數組,使用位矢量必須注明位寬,即數組中的元素個數和排列情況,如:(2)?BIT數據類型。位數據類型也是一個二值的枚舉數SIGNALs1:BIT_VECTOR(7DOWNTO0);--信號s1被定義為一個8位位寬的位矢量,數組元素排列

指示關鍵詞DOWNTO,表示最左位是s1(7),下標名按照降序排列,最右位是s1(0)

SIGNALs2:BIT_VECTOR(0TO7);--信號s2被定義為一個8位位寬的位矢量,數組元素排

列指示關鍵詞TO,表示最左位是s2(0),下標名按照升序排列,最右位是s2(7)SIGNALs1:BIT_VECTOR(7DOW一般而言,DOWNTO更適合于硬件設計者通常的思維方法,即最左邊是權值最高的位(MSB,MostSignificantBit)。下面進一步理解數組排列指示關鍵詞以及數組的賦值和運算。例4-16完成了對信號x、y、z的賦值,其中符號“&”表示串聯,即把操作數或數組合并連接起來組成新的數組,如“0”&“1”&“0”結果為“010”,“001”&“100”結果為“001100”,“100”&“001”結果為“100001”,“VH”&“DL”結果為“VHDL”。例4-17顯示的是對數組進行邏輯運算,需要注意的是,如果對位矢量進行邏輯操作,其結果仍為位操作,如位與。另外,邏輯操作符要求兩個矢量具有相同的長度,并要求被賦值的矢量也是相同的長度。一般而言,DOWNTO更適合于硬件設計者通常的思維方法,【例4-16】

SIGNALx:BIT_VECTOR(1DOWNTO0);

SIGNALy:BIT_VECTOR(0TO1);

SIGNALz:BIT_VECTOR(3DOWNTO0);

SIGNALt:BIT_VECTOR(7DOWNTO0);

x<=a&b; --x(1)=a,x(0)=b

y<=a&b; --y(0)=a,y(1)=b

z<=‘1’&x(1)&y(0); --z=“1aa”

t(7DOWNTO4)<="0001"; --對數組的片的賦值,注意賦值時片的下標方向要與聲明時一致【例4-16】

SIGNALx:BIT_VEC【例4-17】

SIGNALa,b,c,d:BIT_VECTOR(0TO3);

a<=“1010”;

b<=“1000”;

c<=aANDb; --c=“1000”

d<=aORb;--d=“1010”

(4)?CHARACTER數據類型。字符數據類型枚舉了ASCII字符集,用單引號引起來。字符類型區(qū)分大小寫,如:“A”、“a”不同。

(5)?STRING數據類型。字符串數據類型是字符類型的一個非限定數組。字符串類型必須用雙引號引起來,如:“bule”、“abcd”?!纠?-17】

SIGNALa,b,c,(6)?INTEGER數據類型。整數數據類型包括正整數、負整數和零。VHDL語言中,整數使用32位的有符號的二進制數表示,即整數的取值范圍是-231~+231(-2147483647~+2147483647)。在實際應用時,綜合器一般將整型作為無符號數處理,仿真器一般將整型作為有符號數處理。使用整數時,需要利用RANGE子句為所聲明的數限定范圍,然后根據所限定的范圍來決定表示此信號或變量的二進制數的位數。如果在聲明時沒有限定取值范圍,則綜合器會自動采用32位二進制數來表示,假設實際中的整數只需4位二進制數即可,就會造成較大的資源浪費。

整數數據類型的聲明如下:

SIGNALs1:INTEGERRANGE0TO15;--聲明信號s1,數據類型是整型,取值范圍0~15共16個值,可用4位二進制數來表示(6)?INTEGER數據類型。整數數據類型包括正整數(7)?NATURAL數據類型。自然數數據類型是整數類型的子類型,用來表示自然數(即非負的整數)。

(8)?POSITIVE數據類型。正整數數據類型也是整數類型的子類型,包含整數中非零和非負的數值。

(9)?REAL數據類型。實數的取值范圍是-1.0E38~+1.0E38。實數必須帶有小數點。通常情況下,實數類型僅能在仿真器中使用,綜合器不支持實數類型。實數的書寫格式可參見4.1.1節(jié)。

(10)?TIME數據類型。VHDL中唯一的預定物理類型是時間。時間類型包括整數和物理量單位兩個部分,且整數和單位之間至少留一個空格,如2ns、10ms。綜合器也不支持時間類型。(7)?NATURAL數據類型。自然數數據類型是整數類2.IEEE預定義數據類型

IEEE庫是VHDL設計中最為常用的庫,包含IEEE標準的程序包和其他一些支持工業(yè)標準的程序包,如std_logic_1164、numeric_std、numeric_bit、std_logic_arith、std_logic_unsigned、std_logic_signed等。在這些程序包內還定義了一些常用的數據類型,但由于這些程序包并非符合VHDL標準,所以在使用相應的數據類型前,需要在設計的最前面以顯式的形式表達出來。2.IEEE預定義數據類型

IEEE庫是VHDL設IEEE庫中的std_logic_1164這個程序包是IEEE的標準程序包,定義了兩個重要且常用的數據類型:標準邏輯位STD_LOGIC和標準邏輯矢量STD_LOGIC_VECTOR。從前面的內容分析可知,如果要使用這兩個數據類型,必須先通過LIBRARY語句打開IEEE庫,然后通過USE語句顯式調用std_logic_1164這個程序包。

程序包std_logic_arith是由美國Synopsys公司加入IEEE庫的,雖然并非IEEE標準,但已成為事實上的工業(yè)標準。該程序包在std_logic_1164程序包的基礎上擴展了三個數據類型:無符號(UNSIGNED)數據類型、有符號(SIGNED)數據類型以及小整型(SMALL_INT)數據類型,并定義了相關的算數運算符和轉換函數。IEEE庫中的std_logic_1164這個程序包是I在IEEE庫中,numeric_std標準程序包和numeric_bit程序包也定義了UNSIGNED型和SIGNED型數據類型,其中,numeric_std程序包是針對STD_LOGIC數據類型的無符號數和有符號數,而numeric_bit程序包是針對BIT數據類型的。當綜合器中沒有附帶std_logic_arith程序包時,可以使用這兩個程序包。在IEEE庫中,numeric_std標準程序包和num(1)?STD_LOGIC數據類型。STD_LOGIC數據類型共定義了九種取值,分別是:“U”——未初始化;“X”——強未知的;“0”——強0;“1”——強1;“Z”——高阻態(tài);“W”——弱未知的;“L”——弱0;“H”——弱1;“-”——忽略。這就意味著STD_LOGIC數據類型能夠比BIT數據類型描述更多的線路情況,如:“Z”和“-”常用于三態(tài)的描述,“L”和“H”可用于描述下拉和上拉。但就綜合而言,STD_LOGIC數據類型在數字器件中實現的只有其中的四種取值(“0”、“1”、“-”、“Z”)。當然,這九種值對于仿真都有重要的意義。(1)?STD_LOGIC數據類型。STD_LOGIC(2)?STD_LOGIC_VECTOR數據類型。STD_LOGIV_VECTOR數據類型是基于STD_LOGIC的一維數組,即數組中每個元素的數據類型都是STD_LOGIC,采用雙引號引起來。需要注意的是,位寬相同、數據類型相同才能進行賦值或運算操作。STD_LOGIC_VECTOR數據類型的相關操作與BIT_VECTOR數據類型類似,這里不再

贅述。(2)?STD_LOGIC_VECTOR數據類型。ST(3)?STD_ULOGIC和STD_ULOGIC_VECTOR數據類型。STD_ULOGIC數據類型也是在std_logic_1164程序包中定義的,也定義了九種取值,它與STD_LOGIC數據類型的區(qū)別在于:STD_LOGIC數據類型是STD_ULOGIC數據類型的一個子集,是一個決斷類型。所謂決斷是指:如果一個信號由多個驅動源驅動,則需要調用預先定義的決斷函數以解決沖突并確定賦予信號哪個值。由于STD_ULOGIC不是決斷類型,如果一個這樣的信號由兩個以上的驅動源驅動,將導致錯誤。由于STD_ULOGIC的限制,使用STD_LGOIC數據類型更為方便。具體決斷的相關知識請參見7.2.3節(jié)。

同樣地,STD_ULOGIC_VECTOR數據類型是基于STD_ULOGIC數據類型的一維數組。(3)?STD_ULOGIC和STD_ULOGIC_V(4)?UNSIGNED數據類型。UNSIGNED數據類型代表一個無符號的數。在綜合器中,這個數值被解釋為一個二進制數,最左位是最高位。如果聲明一個變量或信號為UNSIGNED數據類型,則其位矢長度越長,所能代表的數值就越大,如:位矢長度為8位,最大值為255。不能使用UNSIGNED聲明負數。例4-18是UNSIGNED數據類型的示例。

【例4-18】

VARIABLEv1:UNSIGNED(0TO7); --聲明變量v1,8位二進制數,最高位為v1(0)

SIGNAL s1:UNSIGNED(7DOWNTO0); --聲明變量s1,最高位為s1(7)(4)?UNSIGNED數據類型。UNSIGNED數據(5)?SIGNED數據類型。SIGNED數據類型表示一個有符號的數,最高位是符號位,一般用“0”表示正,“1”表示負,綜合器將其解釋為補碼。例4-19是SIGNED數據類型的示例。

【例4-19】

ARCHITECTUREbhvOFexIS

SIGNALs1 :SIGNED(3TO0); --聲明信號s1為有符號數

BEGIN

PROCESS(c)

VARIABLEv1:SIGNED(0TO3); --聲明變量v1為有符號數(5)?SIGNED數據類型。SIGNED數據類型表示BEGIN

v1:=“0101”; --最高位v1(0)是符號位,v1=+5

s1<=“1011”; --最高位s1(3)是符號位,s1=-5

(6)?SMALL_INT數據類型。SMALL_INT數據類型是INTEGER數據類型的子類型,按照在std_logic_arith程序包中定義的源代碼,它將INTEGER約束到只含有2個值。程序包std_logic_arith中聲明SMALL_INT的源代碼如下:

SUBTYPESMALL_INTISINTEGERRANGE0TO1;BEGIN

v1:=“01014.3.2用戶自定義數據類型

除了上述預定義數據類型外,用戶還可以定義自己所需的數據類型。一般采用類型定義語句TYPE和子類型定義語句SUBTYPE來實現。

1.TYPE語句

TYPE語句能夠定義一種全新的數據類型,其語法格式如下:

TYPE數據類型名IS數據類型定義[OF基本數據類型];

其中,數據類型名由用戶自行定義,可有多個,采用逗號分開;數據類型定義部分用來描述所定義的數據類型的表達方式和表達內容;關鍵詞OF后的基本數據類型是指數據類型定義中所定義的元素的基本數據類型,一般是已有的預定義數據類型,如:BIT、STD_LOGIC等。例4-20是使用TYPE定義新數據類型并聲明數據對象的示例。4.3.2用戶自定義數據類型

除了上述預定義數據類型【例4-20】

TYPEbtypeISARRAY(7DOWNTO0)OFBIT;

--定義數據類型btype,具有8個元素的數組型,每一個元素的數據類型都是BIT

TYPEcolorIS(blue,green,red,yellow);--定義數據類型color,共有4個元素,屬于枚舉類型

SIGNAL s1 :btype; --聲明信號s1為btype型

VARIABLEv1 :color; --聲明變量v1為color型

...

s1<=“10001000”; --對s1賦值

v1:=green; --對v1賦值【例4-20】

TYPEbtypeISARRA2.SUBTYPE語句

SUBTYPE語句定義子類型,即已有數據類型的子集,它滿足原數據類型(稱為基本數據類型)的所有約束條件。子類型定義的語法格式如下:

SUBTYPE子類型名IS基本數據類型[范圍];

子類型的定義只是在基本數據類型的基礎上作一些約束,它并沒有定義新的數據類型。上述的POSITIVE和NATURAL就是INTEGER數據類型的子類型。只要值在合適的子類型范圍內,這些子類型都可以完成相加、乘、比較、賦值等操作。例4-21給出了POSITIVE和NATURAL之間的有效和無效的賦值示例。例4-22是子類型定義示例。2.SUBTYPE語句

SUBTYPE語句定義子類型【例4-21】

VARIABLEv_n:NATURAL;--聲明變量v_n為NATURAL類型

VARIABLEv_p:POSITIVE;--聲明變量v_p為POSITIVE類型

...

v_n:=0; --對v_n賦值0

v_p:=v_n; --把v_n賦值給v_p,此處錯誤,0超過了POSITIVE數據類型的取值范圍

...

v_p:=5; --對v_p賦值5

v_n:=v_p+1; --把v_p+1賦值給v_n,賦值有效【例4-21】

VARIABLEv_n:NAT【例4-22】

SUBTYPEmy_intISINTEGERRANGE0TO1023;--定義子類型my_int,取值范圍0~1023

SUBTYPEmy_stdISSTD_LOGIC_VECTOR(15DOWNTO0);--定義子類型my_type,16位數組

TYPEbtypeISARRAY(NATURALRANGE<>)OFBIT;--定義btype為非限定BIT數組

SUBTYPEmy_typeISbtype(0TO15); --定義my_type為btype數據類型的子類型

下面以一個實例進一步說明TYPE語句和SUBTYPE語句定義的數據類型的區(qū)別。【例4-22】

SUBTYPEmy_intISIN【例4-23】【例4-23】EDA技術和VHDL設計第4章VHDL語言要素課件編譯例4-23,軟件會報錯,具體錯誤原因如圖4-7所示,即輸入信號d并不符合btype數據類型。從例4-23的L12行可以看到,定義了一個數據類型btype,是一個有4個元素的數組,每個元素的數據類型都是STD_LOGIC;輸入信號d的數據類型為標準邏輯矢量。雖然從表面來看,二者的形式完全一致,但它們不是一種數據類型,所以不能完成賦值操作。再次強調,使用TYPE語句定義的類型是一個全新的數據類型,VHDL不允許不同的數據類型直接進行操作運算,必須進行數據類型的轉換。如果將L12行改為“SUBTYPEbtypeISSTD_LOGIC_VECTOR(3DOWNTO0);”,即使用子類型定義語句,該例將能通過編譯。子類型與其基本數據類型屬于同一種數據類型,所以屬于子類型的和屬于基本數據類型的數據對象間的相互賦值可以直接進行,而不必進行數據類型的轉換。編譯例4-23,軟件會報錯,具體錯誤原因如圖4-7所示,圖4-7例4-23編譯出錯信息圖4-7例4-23編譯出錯信息3.常用用戶自定義類型

VHDL常用的用戶自定義數據類型有:枚舉類型、整數類型、數組類型、記錄類型等。

(1)枚舉類型。顧名思義,枚舉類型即為通過枚舉該類型的所有可能值來定義。枚舉類型的示例如例4-24所示。

【例4-24】

TYPEcolorIS(blue,green,red,yellow); --定義數據類型color,共有4個元素

TYPEmy_std_logicIS('0','1','Z','-'); --定義數據類型my_std_logic,包含4個元素3.常用用戶自定義類型

VHDL常用的用戶自定義數據在使用狀態(tài)機進行VHDL設計時,一般采用枚舉類型來枚舉所有的狀態(tài)。具體狀態(tài)機的設計方法參見第6章。在綜合時,會把用文字符號表示的枚舉值用一組二進制數來表示,稱為枚舉編碼。編碼比特向量的長度由枚舉值的個數所決定,一般確定為所需表達的最少比特數。例4-24中的枚舉類型color,需要2bit的編碼向量就能完成對所有值的表示。如果一個枚舉類型有5個值,則需要3bit的編碼向量。默認的編碼方式是順序編碼,如:blue=“00”,green=“01”,red=“10”,yellow=“11”。在使用狀態(tài)機進行VHDL設計時,一般采用枚舉類型來枚舉所當然,也可以不采用枚舉默認編碼的方式,而利用enum_encoding屬性來實現自己的編碼。enum_encoding屬性是由綜合器供應商提供的一個常用的用戶自定義屬性,有關預定義屬性和用戶自定義屬性的相關內容請參見4.5節(jié)。例4-25顯示了如何利用enum_encoding屬性更改默認編碼。

【例4-25】

ATTRIBUTEenum_encoding:STRING;--屬性聲明

ATTRIBUTEenmu_encodingOFcolor:TYPEIS"11001001";--屬性描述當然,也可以不采用枚舉默認編碼的方式,而利用enum_e(2)整數類型。?此處自定義的整數類型即為使用TYPE語句或SUBTYPE語句根據實際需要,利用關鍵詞RANGE限定整數的取值范圍,提高芯片資源的利用率。整數類型的示例如下。

【例4-26】

TYPEint1ISRANGE0TO100; --7bit矢量

TYPEint2ISRANGE-100TO100; --8bit矢量,最高位是符號位

SUBTYPEint3ISint2RANGE0TO15; --4bit矢量

需要注意的是,VHDL綜合器對整數的編碼方式:如果是負數,則編碼為二進制補碼;如果是正數,則編碼為二進制原碼。(2)整數類型。?此處自定義的整數類型即為使用TYPE(3)數組類型。數組是同類型元素的集合,可以是一維數組、二維數組或一維×一維數組,當然也可以是更高維數的數組,但VHDL綜合器通常不支持更高維數的數組。其實前面講述VHDL預定義數據類型時已經接觸過一維數組了,如BIT_VECTOR、STD_LOGIC_VECTOR。圖4-8進一步解釋數組的構成,(a)顯示單個元素;(b)顯示一維數組;(c)顯示一維?×?一維數組;(d)顯示二維數組。(3)數組類型。數組是同類型元素的集合,可以是一維數組圖4-8數組構成示意圖4-8數組構成示意VHDL既允許限定數組,又允許非限定數組,二者的區(qū)別在于:限定數組下標的取值范圍在數組定義時就被確定了,而非限定數組下標的取值范圍留待具體數據對象使用時再確定。

限定數組定義語法的格式如下:

TYPE數組名ISARRAY(數組范圍)OF數據類型;

其中,數組名是新定義的限定數組類型的名稱;數組范圍明確指出數組元素的數量和排列形式,以整數來表示數組下標;數據類型即為數組內各元素的數據類型。VHDL既允許限定數組,又允許非限定數組,二者的區(qū)別在于非限定數組定義語法的格式如下:

TYPE數組名ISARRAY(數組下標名RANGE<>)OF數據類型;

其中,數組名是新定義的非限定數組類型的名稱;數組下標名是一個整數類型或子類型的名稱;符號?<>?表示下標范圍待定,用到該數組類型時,再填入具體的取值范圍;數據類型為數組中每個元素的數據類型。

限定數組示例見例4-27,非限定數組示例見例4-28。非限定數組定義語法的格式如下:

TYPE數組名I【例4-27】

TYPEbtypeISARRAY(7DOWNTO0)OFBIT;

--限定數組類型btype,有8個元素,下標排列是7、6、5、4、3、2、1、0

SIGNALs1:btype;; --聲明信號s1,數據類型為限定數組btype【例4-27】

TYPEbtypeISARRA【例4-28】

TYPEmy_stdISarray(NATURALRANGE<>)OFSTD_LOGIC;

--非限定數組類型my_std,下標可以取值在自然數范圍內

VARIABLEv1:my_std(1TO8); --聲明變量v1,將數組的取值范圍確定為1~8

TYPEmy_std1ISarray(INTEGERRANGE<>)OFSTD_LOGIC;

--非限定數組類型-my_std1,下標可以取值在整數范圍內

VARIABLEv2:my_std1(-3TO4); --聲明變量v2,將數組的取值范圍確定為-3~4【例4-28】

TYPEmy_stdISarr例4-29顯示一維?×?一維數組的定義。

【例4-29】例4-29顯示一維?×?一維數組的定義。

【例4-2例4-30顯示一個二維數組的定義。

【例4-30】

TYPEmatrix2DISARRAY(0TO3,7DOWNTO0)OFSTD_LOGIC;

需要注意的是,二維數組的結構是建立在單個元素上的,而不像一維?×?一維數組是建立在矢量上的。

對一維數組的賦值在4.3.1節(jié)中已經講解,這里不再贅述。當給一個一維?×?一維或二維數組賦值時,可以有多種方法,具體見例4-31。例4-30顯示一個二維數組的定義。

【例4-30】

【例4-31】【例4-31】EDA技術和VHDL設計第4章VHDL語言要素課件(4)記錄類型。記錄類型和數組類型非常相似,所不同的是記錄類型所包含的元素的數據類型不相同。記錄類型定義語法的格式如下:

TYPE記錄類型名ISRECORD

元素名:元素數據類型;

元素名:元素數據類型;

ENDRECORD[記錄類型名];(4)記錄類型。記錄類型和數組類型非常相似,所不同的是例4-32顯示如何定義一個記錄類型并對其賦值。從例4-32中可以看到,對記錄類型的數據對象賦值,既可以對其中的單個元素進行賦值,也可以采用整體賦值的形式。對單個元素進行賦值,在記錄類型對象名后加點(“.”),再跟賦值元素的元素名。對整體賦值時,有兩種表達方式:名稱關聯和位置關聯。使用名稱關聯方式時,賦值項可以以任何順序出現,如s2<=(int=>15,btype=>"11110000");?等價于例4-32中的s2賦值。使用位置關聯方式時,元素的賦值順序必須與記錄類型聲明時的順序相同??梢允褂肙THERS選項對元素進行賦值,但如果有兩個或更多元素都由OTHERS選項來賦值,則這些元素必須具有相同的數據類型。例4-32顯示如何定義一個記錄類型并對其賦值。從例4-3【例4-32】

TYPEmy_recordISRECORD--定義記錄類型my_record

btype :BIT_VECTOR(7DOWNTO0);

int :INTEGERRANGE0TO15;

ENDRECORD;

SIGNALs1,s2,s3,s4:my_record;

...

s1.btype<="00010001"; --單個元素賦值

<=6; --單個元素賦值

s2<=(btype=>"11110000",int=>15); --名稱關聯方式

s4<=("00000001",OTHERS=>0); 【例4-32】

TYPEmy_recordI4.3.3數據類型的轉換

VHDL是一種強類型語言,不允許不同的數據類型之間直接進行操作,如算術運算、邏輯運算等。所以,設計者常常需要將數據類型進行轉換。設計者可以通過調用預先定義在程序包中的函數來進行數據類型的轉換,也可以自定義轉換函數。

如果兩種數據類型是密切相關的(所有抽象數字類型,如整數類型和實數類型),則可以采用數據類型名稱來實現直接轉換。?例4-33顯示了整數類型和實數類型間的轉換。例4-34再一次體現數據類型間的直接轉換方式。4.3.3數據類型的轉換

VHDL是一種強類型語言,【例4-33】

VARIABLEv1,v2:INTEGER;

v1:=INTEGER(25.63*REAL(v2));

【例4-34】

TYPElongISINTEGERRANGE-100TO100;

TYPEshortISINTEGERRANGE-10TO10;

SIGNALs1:long;

SIGNALs2:short;

...

s1<=s2+5; --錯誤,數據類型不匹配

s1<=long(s2+5); --正確,最后賦值給s1,數據類型為long【例4-33】

VARIABLEv1,v2當然,在std_logic_1164、std_logic_arith、std_logic_unsigned、std_logic_signed中還提供了很多數據類型轉換函數,用于不同數據類型間的轉換,具體轉換函數的定義可參見附錄A。

std_logic_1164程序包所包含的轉換函數如下:當然,在std_logic_1164、std_logicstd_logic_arith程序包所包含的轉換函數如下:std_logic_arith程序包所包含的轉換函數如下例4-35調用了程序包std_logic_1164中的轉換函數to_stdlogicvector和程序包std_logic_arith中的conv_std_logic_vector實現數據類型的轉換。

【例4-35】例4-35調用了程序包std_logic_1164中的轉EDA技術和VHDL設計第4章VHDL語言要素課件4.4VHDL操作符

VHDL的各種表達式是由操作數和操作符組成的,其中操作數是各種運算的對象,而操作符是規(guī)定運算的方式。VHDL提供了七種類型的預定義操作符,分別是:分配操作符(AssignmentOperators)、邏輯操作符(LogicOperators)、算術操作符(ArithmeticOperators)、關系操作符(RelationalOperators)、移位操作符(ShiftOperators)、串聯操作符(ConcatenationOperators)和符號操作符(SignOperators)。使用操作符完成運算,需要特別注意兩點:第一,操作數是相同的數據類型,如果是矢量則需要有相同的長度;第二,操作數的數據類型與操作符所要求的數據類型一致。4.4VHDL操作符

VHDL的各種表達以下逐一介紹每一種操作符。

4.4.1分配操作符

分配操作符用于對信號、變量、常量分配數值,其實在之前的講述中已經多次用到,又稱為賦值操作符。分配操作符包含三個:

(1)?<= 用于對信號賦值;

(2)?:= 用于對變量賦值;

(3)?=> 用于對單個數組元素賦值或OTHERS賦值。以下逐一介紹每一種操作符。

4.4.1分配操作符

【例4-36】

SIGNALs1 :STD_LOGIC;

SIGNALs2,s3 :STD_LOGIC_VECTOR(7DOWNTO0);

...

VARIABLEv1 :STD_LOGIC_VECTOR(7DOWNTO0);

...

s1<=‘1’;

s2<=“11000011”;

s3<=(0,2,3=>‘1’,OTHERS=>‘0’); --s3=“00001101”

v1:="00010001";【例4-36】

SIGNALs1 :STD_L4.4.2邏輯操作符

邏輯操作符用于完成邏輯運算,包含七個:

(1)?NOT 取反;

(2)?AND 與;

(3)?OR 或;

(4)?NAND 與非;

(5)?NOR 或非;

(6)?XOR 異或;

(7)?XNOR 同或。4.4.2邏輯操作符

邏輯操作符用于完成邏輯運算,包邏輯操作符支持對BOOLEAN、BIT、BIT_VECTOR、STD_LOGIC、STD_LOGIC_VECTOR、STD_ULOGIC以及STD_ULOGIC_VECTOR數據類型的運算。需要注意的是,在這七種邏輯操作符中,NOT優(yōu)先于其他任意邏輯操作符,剩下的六種邏輯操作符具有相同的優(yōu)先級。XNOR操作符定義在VHDL93標準中。由于AND、OR、XOR這三個操作符的運算結果不會因為運算次序的不同而改變。所以,如果在一串運算中,只用到這三個操作符中的一個,可以不使用括號;如果一串運算中的操作符不同或有連續(xù)多個除上述三個操作符外的操作符,則必須使用括號。另外,邏輯操作符是按位操作。例4-37顯示了一些正確和錯誤的邏輯操作符的使用示例。邏輯操作符支持對BOOLEAN、BIT、BIT_VECT【例4-37】

SIGNALa,b,c,d :STD_LOGIC_VECTOR(3DOWNTO0);

SIGNAL e,f,g,h :BIT_VECTOR(1DOWNTO0);

SIGNALi,j,k,l :STD_LOGIC;

...

c<=NOTaANDb; --正確,NOT優(yōu)先級最高,相當于(NOTa)ANDb

d<=aANDbANDc; --正確,兩個操作符都是AND,可以不加括號

g<=NOT(dANDe); --錯誤,矢量長度不匹配

h<=eNANDfNANDg; --錯誤,兩個或以上的NAND符號必須加括號

k<=iNANDj; --正確

l<=iORjXORk; --錯誤,多個操作符必須加括號【例4-37】

SIGNALa,b,c,d 4.4.3算術操作符

算術操作符用于完成算術運算,可支持的數據類型包括:INTEGER、SIGNED、UNSIGNED以及REAL(REAL數據類型不能被綜合)。算術操作符包含以下八個:

(1)?+ 加;

(2)?- 減;

(3)?* 乘;

(4)?/ 除;

(5)?** 乘方;

(6)?MOD 取模;

(7)?REM 取余;

(8)?ABS 取絕對值。4.4.3算術操作符

算術操作符用于完成算術運算,可八個算術操作符可分為三類,分別是:加減操作符、乘除操作符和混合操作符。

1.加減操作符

“+”、“-”操作符的運算規(guī)則與常規(guī)的加減法是一致的。加減操作符示例見例4-38。

【例4-38】

SIGNALs1,s2,s3,s4:INTEGERRANGE0TO255;

...

s3<=s1+s2;

s4<=s1-s2;八個算術操作符可分為三類,分別是:加減操作符、乘除操作符【例4-39】【例4-39】例4-39的目的是完成一個4位的二進制加法器,在時鐘上升沿到來時進行加1計數。但是在編譯時卻出現了如圖4-9所示錯誤:不能確定“+”的定義。觀察L15可以發(fā)現,信號reg的數據類型是STD_LOGIC_VECTOR,而1是整型。按照前面對算術操作符的講述可知,其支持的數據類型并不包括STD_LOGIC_VECTOR,所以不能完成數據類型STD_LOGIC_VECTOR和INTEGER的相加操作。其實,在IEEE庫中的std_logic_unsigned或者std_logic_signed程序包中,重新定義了加、減算術操作符,使其可以在STD_LOGIC_VECTOR與STD_LOGIC_VECTOR數據類型以及STD_LOGIC_VECTOR與INTEGER數據類型間進行加法和減法運算,具體函數定義參見附錄A。這類函數名稱相同,但所定義的操作數的數據類型不同的函數,被稱為重載函數。所以,例4-39只需要在L3行后加上語句USEieee.std_logic_unsigned.all表示允許使用該程序包內的預定義函數,就能實現reg和1的無符號相加。如果調用的是程序包std_logic_signed,則能夠實現有符號相加。例4-39的目的是完成一個4位的二進制加法器,在時鐘上升圖4-9例4-39錯誤信息圖4-9例4-39錯誤信息2.乘除操作符

VHDL的乘除操作符包含4個:“?*?”、“?/?”、“MOD”和“REM”,其中“MOD”和“REM”的本質與除法操作是一致的。需要注意的是,從優(yōu)化的角度出發(fā),最好不要輕易使用乘除操作符,因為當位數較多時,將會占用非常多的硬件資源,如16位的“?*?”運算將耗費幾百個邏輯單元才能實現。乘除運算可以通過其他變通的方法來實現,如:移位相加、LPM模塊、DSP模塊等。

“MOD”和“REM”的操作數類型只能是整數,且運算結果也是整數。如果操作數都是正整數,則“MOD”和“REM”運算結果相同,都可以看做普通取余運算。但如果操作數出現負整數的情況,二者運算結果不同。例4-40顯示了“MOD”與“REM”運算結果的差別。2.乘除操作符

VHDL的乘除操作符包含4個:“?*【例4-40】【例4-40】例4-40的仿真結果見圖4-10??梢钥吹疆敳僮鲾刀际钦麛禃r,二者結果完全一致。還可以得到如下結論:

(1)?“MOD”運算結果的正負與操作數b的正負相同,如:5MOD3?=?2,5MOD(-3)=?-1。

(2)?“REM”運算結果的正負與操作數a的正負相同,如:5REM3?=?2,(-5)REM3?=?-2。

具體來說,二者的運算都可以套用公式a?-?b?×?N來計算,只是N的取值不同。當進行“MOD”運算時,N為除法結果向負無窮取整;而進行“REM”運算時,N為除法結果向零取整。如:5/-3的除法結果向負無窮取整是?-2,而向零取整是?-1,所以“MOD”運算的結果等于5?-?(-3)?×?(-2)=-1,而“REM”運算的結果等于5?-?(-3)?×?(-1)=2。例4-40的仿真結果見圖4-10。可以看到當操作數都是正圖4-10例4-40仿真結果圖4-10例4-40仿真結果3.混合操作符

混合操作符包含“**”和ABS操作符,示例如下。

【例4-41】

SIGNALa :INTEGERRANGE0TO7:=3;

SIGNALb :INTEGERRANGE0TO7:=2;

SIGNALc :INTEGERRANGE-7TO7:=-5;

y<=a**b;

z<=abs(c);3.混合操作符

混合操作符包含“**”和ABS操作符4.4.4關系操作符

關系操作符的作用是將相同數據類型的數據

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論