一個VHDL程序代碼包含實體(entity)、結構體(architecture)、配置(configuration)、程序包(package)、庫(library)等。
一、數據類型
1.用戶自定義數據類型
使用關鍵字TYPE,例如:
TYPE my_integer IS RANGE -32 TO 32;
–用戶自定義的整數類型的子集
TYPE student_grade IS RANGE 0 TO 100;
–用戶自定義的自然數類型的子集
TYPE state IS (idle, forward, backward, stop);
–枚舉數據類型,常用于有限狀態機的狀態定義
一般來說,枚舉類型的數據自動按順序依次編碼。
2.子類型
在原有已定義數據類型上加一些約束條件,可以定義該數據類型的子類型。VHDL不允許不同類型的數據直接進行操作運算,而某個數據類型的子類型則可以和原有類型數據直接進行操作運算。
子類型定義使用SUBTYPE關鍵字。
3.數組(ARRAY)
ARRAY是將相同數據類型的數據集合在一起形成的一種新的數據類型。
TYPE type_name IS ARRAY (specification) OF data_type;
–定義新的數組類型語法結構
SIGNAL signal_name: type_name [:= initial_value];
–使用新的數組類型對SIGNAL,CONSTANT, VARIABLE進行聲明
例如:
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);
–濾波器系數類型定義
SIGNAL delay_regs: delay_lines;– 信號延遲寄存器聲明
CONSTANT coef: coeffs := (); –常量系數聲明并賦初值
4.端口數組
在定義電路的輸入/輸出端口時,有時需把端口定義為矢量陣列,而在ENTITY中不允許使用TYPE進行類型定義,所以必須在包集(PACKAGE)中根據端口的具體信號特征建立用戶自定義的數據類型,該數據類型可以供包括ENTITY在內的整個設計使用。
—————————————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位的數組
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.有符號數和無符號數
要使用SIGNED和UNSIGNED類型數據,必須在代碼開始部分聲明ieee庫中的包集std_logic_arith。它們支持算術運算但不支持邏輯運算。
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;–非法(不支持邏輯運算)
——————————————————————————-
STD_LOGIC_VECTOR類型的數據不能直接進行算術運算,只有聲明了std_logic_signed和std_logic_unsigned兩個包集后才可以像SIGNED和UNSIGNED類型的數據一樣進行算術運算。
6.數據類型轉換
在ieee庫的std_logic_arith包集中提供了許多數據類型轉換函數:
1. conv_integer(p): 將數據類型為INTEGER,UNSIGNED,SIGNED,STD_ULOGIC或STD_LOGIC的操作數p轉換成INTEGER類型。不包含STD_LOGIC_VECTOR。
2. conv_unsigned(p,b):將數據類型為INTEGER,UNSIGNED,SIGNED或STD_ULOGIC的操作數p轉換成位寬為b的UNSIGNED類型數據。
3. conv_signed(p,b):將數據類型為INTEGER, UNSIGNED, SIGNED或STD_ULOGIC的操作數p轉換成位寬為b的SIGNED類型的數據。
4. conv_std_logic_vector(p, b):將數據類型為INTEGER, UNSIGNED, SIGNED或STD_LOGIC的操作數p轉換成位寬為b的STD_LOGIC_VECTOR類型的數據。
二、運算操作符和屬性
1.運算操作符
l賦值運算符
賦值運算符用來給信號、變量和常數賦值。
《=用于對SIGNAL類型賦值;
:=用于對VARIABLE,CONSTANT和GENERIC賦值,也可用于賦初始值;
=》用于對矢量中的某些位賦值,或對某些位之外的其他位賦值(常用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
l邏輯運算符
操作數必須是BIT, STD_LOGIC或STD_ULOGIC類型的數據或者是這些數據類型的擴展,即BIT_VECTOR, STD_LOGIC_VECTOR,STD_ULOGIC_VECTOR。
VHDL的邏輯運算符有以下幾種:(優先級遞減)
?NOT —— 取反
?AND —— 與
?OR —— 或
?NAND —— 與非
?NOR —— 或非
?XOR —— 異或
l算術運算符
操作數可以是INTEGER, SIGNED, UNSIGNED, 如果聲明了std_logic_signed或std_logic_unsigned,可對STD_LOGIC_VECTOR類型的數據進行加法或減法運算。
+ —— 加
-—— 減
* —— 乘
/ —— 除
** —— 指數運算
MOD —— 取模
REM —— 取余
ABS —— 取絕對值
加,減,乘是可以綜合成邏輯電路的;除法運算只在除數為2的n次冪時才能綜合,此時相當于對被除數右移n位;對于指數運算,只有當底數和指數都是靜態數值(常量或GENERIC參數)時才是可綜合的;對于MOD運算,結果的符號同第二個參數的符號相同,對于REM運算,結果的符號同第一個參數符號相同。
l關系運算符
=, /=,
左右兩邊操作數的類型必須相同。
l移位操作符
其中左操作數必須是BIT_VECTOR類型的,右操作數必須是INTEGER類型的(可以為正數或負數)。
VHDL中移位操作符有以下幾種:
usll邏輯左移– 數據左移,右端補0;
usrl邏輯右移– 數據右移,左端補0;
usla算術左移– 數據左移,同時復制最右端的位,填充在右端空出的位置;
usra算術右移– 數據右移,同時復制最左端的位,填充在左端空出的位置;
urol循環邏輯左移 — 數據左移,從左端移出的位填充到右端空出的位置上;
uror循環邏輯右移 – 數據右移,從右端移出的位填充到左端空出的位置上。
例:x 《= “01001”,那么:
y 《= x sll 2;–邏輯左移2位,y《=”00100”
y 《= x sla 2;–算術左移2位,y《=”00111”
y 《= x srl 3;–邏輯右移3位,y《=”00001”
y 《= x sra 3;–算術右移3位,y《=”00001”
評論
查看更多