Hằng là một đối tượng mà nó được khởi tạo để chỉ ra một giá trị cố định và không bị thay đổi. Khai báo hằng được phép khai báo trong các đóng gói, các Entity, các kiến trúc, các chương trình con, các khối, và trong phát biểu của các quá trình processes.
Cú pháp khai báo hằng như sau:
Constant constant_name {,constant_name}: type := <value>;
Ví dụ:
constant YES : BOOLEAN:= TRUE;
constant CHAR7: BIT_VECTOR (4 downto 0 ):="00111"; constant MSB: INTEGER:=5;
3.2.2. Các biến (Variables)
Các biến được dùng để lưu dữ liệu tạm thời, chúng chỉ được phép khai báo trong phát biểu Process hoặc các chương trình con.
Ví dụ:
variable X,Y : BIT;
variable TEMP: BIT_VECTOR (8 downto 0) ; variable DELAY: INTERGER range 0 to 15:=5;
3.2.3. Các kiểu tín hiệu (Signals)
Tín hiệu được dùng để kết nối các Entity của thiết kế lại với nhau và trao đổi các giá trị biến đổi ở trong phát biểu process. Chúng có thể được xem như các dây dẫn hay các bus nối ở trong mạch thực tế. Tín hiệu có thể được khai báo trong các đóng gói (Package), trong các khai báo Entity, trong khai báo kiến trúc (Architecture), trong các khối (Block). Với các tín hiệu được khai báo trong các package thì tín hiệu này được gọi là tín hiệu toàn cục (các thiết kế có thể sử dụng chúng ), các tín hiệu được khai báo trong Entity là tín hiệu toàn cục trong một Entity, tương tự với tín hiệu được khai báo trong một kiến trúc, nó là tín hiệu dùng chung trong một kiến trúc đó.
Cú pháp của chúng có dạng như sau:
Signal Signal_name {,signal_name}: type [:=value];
signal BEEP : BIT:= '0';
signal TEMP: STD_LOGIC_VECTOR (8 downto 0); signal COUNT: INTEGER range 0 to 100 :=5;
3.3. CÁC KIỂU DỮ LIỆU
Tất cả các đối tượng dữ liệu trong VHDL cần phải được định nghĩa với một kiểu dữ liệu. Một khai báo kiểu phải chỉ ra tên và dải của kiểu đó. Khai báo kiểu dữ liệu được phép khai báo trong phần khai báo các đóng gói, trong phần khai báo Entity, trong phần khai báo kiến trúc, trong phần khai báo các chương trình con và trong phần khai báo các Process. Các kiểu dữ liệu bao gồm các kiểu sau:
- Kiểu liệt kê. - Kiểu nguyên.
- Các kiểu dữ liệu tiền định nghĩa. - Kiểu mảng.
- Kiểu bản ghi.
- Kiểu dữ liệu chuẩn logic.
- Kiểu dữ liệu có dấu và không dấu. - Các kiểu phụ.
3.3.1. Các kiểu liệt kê (ENUMERATION)
Một kiểu liệt kê được chỉ ra bởi việc liệt kê các giá trị cho phép của kiểu đó. Tất cả các giá trị được định nghĩa bởi người dùng có thể là các tên định danh, hoặc các các kiểu chữ ký tự. Tên định danh thực chất là một tên do người dùng đặt ra, chẳng hạn như blue, ball, monday. Kiểu chữ ký tự là kiểu của các ký tự có kèm theo dấu nháy đơn, chẳng hạn như 'x', ' 0'...
Cú pháp khai báo của chúng như sau:
Type type_name is (enumerattion_literal {, enumeration_literal});
Với type_name là một tên định danh và mỗi enumerattion_literal hoặc là một tên định danh hoặc là một chữ ký tự.
Ví dụ:
type COLOR is (RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE); type DAY is (MONDAY, TUESDAY,WEDNESDAY,THURDAY,FRIDAY); type STD_LOGIC is ('U','X','0','1','Z','W','L','H','_');
Mỗi một định danh trong một kiểu đều có một vị trí nhất định trong kiểu, chúng được xác định bởi thứ tự xuất hiện của chúng trong kiểu đó. Trong ví dụ trên, mặc định RED có vị trí 0, ORANGE sẽ có vị trí 1.... Nếu chúng ta khai báo một đối tượng dữ liệu với kiểu là COLOR và không định nghĩa giá trị khởi tạo thì đối tượng
dữ liệu sẽ được khởi tạo mặc định ở vị trí đầu tiên của kiểu liệt kê (vị trí không), trong trường hợp này COLOR sẽ nhận giá trị RED.
3.3.2. Kiểu nguyên
Kiểu nguyên là các kiểu số nguyên, chúng được dùng cho các phép tính, các chỉ số, các điều khiển số vòng lặp. Trong hầu hết các kiểu thực thi trong VHDL có dải từ - 2,147,483,647 đến + 2,147,483,647. Cú pháp của chúng được khai báo như sau:
type type_name is range - 2,147,483,647 to + 2, 147, 483,647;
Ví dụ:
type INTEGER is range - 2,147,483,647 to + 2, 147, 483,647; type COUNT is range 0 to 10;
3.3.3. Các kiểu dữ liệu tiền định nghĩa trong VHDL
IEEE định nghĩa hai gói dữ liệu STANDARD và TEXTIO trong thư viện STD. Mỗi một gói dữ liệu này có chứa một loạt các kiểu và các phép tính chuẩn. Dưới đây là các kiểu dữ liệu được định nghĩa trong gói STANDARD:
- BOOLEAN: Một kiểu liệt kê với hai giá trị True và False, các thao tác Logic
và các phép toán quan hệ sẽ trả về giá trị Boolean.
- BIT: Một kiểu liệt kê với hai giá trị '0' và '1', các phép tính logic có thể lấy và
trả về giá trị kiểu BIT.
- CHARACTER: Kiểu liệt kê của các mã ASCII.
- INTEGER: Được dùng để miêu tả các số âm và dương. Dải hoạt động của chúng được ấn định từ - 2,147,438,647 đến 2,147,438,647. Các hàm toán học như cộng, trừ, nhân, chia được hỗ trợ kiểu nguyên.
- NATURE: Các kiểu con của kiểu nguyên được dùng để miêu tả các số kiểu tự
nhiên (không âm).
- POSITIVE: Các kiểu con của kiểu nguyên được dùng để miêu tả các số
dương.
- BIT_VECTOR: Được dùng để miêu tả một mảng các giá trị kiểu BIT.
- STRING: Một mảng các ký tự, một giá trị kiểu chuỗi được đi kèm bởi dấu
nháy kép.
- REAL: Được dùng để mô tả các kiểu số thực, dải hoạt động từ -1.0E+38 đến
+1.0E+38.
- Kiểu thời gian vật lý: Mô tả các giá trị thời gian được dùng trong mô phỏng.
Có một vài kiểu dữ liệu được định nghĩa trong gói STANDARD như sau:
Type BOOLEAN is ( fase, true); Type BIT is ( '0', '1' );
Type INTEGER is range -2,147,483,648 to 2,147,483,648; Type REAL is Range -1.0E38 to 1.0E38;
Type CHARACTER is (nul, soh, stx, eot, enq, ack, bel,...);
3.3.4. Kiểu mảng
Kiểu mảng là kiểu của nhóm các phần tử có cùng kiểu giống nhau. Có hai kiểu mảng như sau:
- Kiểu mảng được gán kiểu. - Kiểu mảng không bị gán kiểu.
Kiểu mảng bị gán kiểu là kiểu mà các chỉ số mảng của chúng được định nghĩa tường minh.
Cú pháp của chúng như sau:
type array_type_name is array (discrete_range) of subtype_indication;
Ở đây array_type_name là tên của kiểu mảng được ép kiểu, discrete_range kiểu phụ của kiểu nguyên khác hoặc kiểu liệt kê, subtype_indication chính là kiểu của mỗi phần tử của mảng.
Kiểu mảng không bị gán kiểu là kiểu mà chỉ số mảng của chúng không bị chỉ ra, nhưng các kiểu chỉ số của chúng phải được chỉ ra. Cú pháp của chúng được chỉ ra như sau:
type array_type_name is array (type_name range <>) of subtype_indication;
Ví dụ 1:
type A1 is array ( 0 to 31) of INTEGER;
type Bit_Vector is arrray (NATURAL range <>) of BIT;
type STRING is array (POSITIVE range <>) of CHARACTER;
A1 là một mảng gồm 32 phần tử mà trong đó mỗi phần tử là một kiểu nguyên. Một ví dụ khác chỉ ra kiểu Bit_vector và kiểu String được tạo ra trong chuẩn các gói STANDARD.
Ví dụ 2:
subtype B1 is BIT_VECTOR ( 3 downto 0); variable B2 : BIT_VECTOR (0 to 10);
Dải chỉ số xác định số phần tử trong mảng và hướng của chúng (low to high | high to low).
VHDL cho phép khai báo các mảng nhiều chiều để có thể dùng để khai báo các mẫu RAM và ROM. Xem ví dụ dưới đây:
type Mat is array (0 to 7, 0 to 3) of BIT;
constant ROM : MAT : = (( '0', '1', '0', '1'), ('1', '1', '0', '1' ),
('0', '1', '1', '1' ), ('0', '1' , '0', '0' ), ('0', '0' ,'0' , '0'), ('1', '1' , '0', '0' ), ('1', '1' , '1', '1' ), ('1', '1' , '0', '0' )); X := ROM (4,3);
Biến X sẽ lấy giá trị '0' được tô đậm không in nghiêng.
3.3.5. Kiểu Record
Kiểu record là một nhóm có nhiều hơn một phần tử có các kiểu khác nhau. Phần tử của Record bao gồm các phần tử của bất cứ kiểu nào, nó có thể là các kiểu mảng hoặc kiểu Record.
Ví dụ:
type DATE_TYPE is ( SUN, MON, TUE , WED , THR , FRI , SAT) ; type HOLIDAY is
record
YEAR : INTEGER range 1900 to 1999; MONTH : INTEGER range 1 to 12 ; DAY : INTEGER range 1 to 31; DATE : DATE_TYPE;
end record ; signal S : HOLIDAY;
variable T1: integer range 1900 to 1999; variable T2 : DATE_TYPE;
T1: = S.YEAR; T2:= S.DATE; S.DAY <= 30;
3.3.6. Các kiểu STD_LOGIC
Để tạo mẫu các đường tín hiệu có nhiều hơn hai giá trị ( '0' , '1' ), VHDL định nghĩa chín khoảng trong gói chuẩn. Chín giá trị bao gồm:
type STD_LOGIC is ( 'U' -- không khởi tạo giá trị 'X' -- Không xác định '0' -- Kiểu mức thấp
'1' -- Kiểu mức cao 'Z' -- Kiểu trở kháng cao
'W' -- Không xác định ở mức yếu 'L' -- Mức thấp yếu
'H' -- Mức cao yếu
'_' -- Không quan tâm đến giá trị.);
Tương tự như kiểu BIT và kiểu BIT_VECTOR, VHDL cung cấp một kiểu khác gọi là STD_LOGIC_VECTOR.
Để sử dụng các định nghĩa và các hàm trong gói chuẩn logic, các phát biểu sau đây cần được phải khai báo đính kèm theo chương trình.
Library IEEE;
USE IEEE.STD_LOGIC_1164.all;
3.3.7. Các kiểu dữ liệu có dấu và không dấu
Các kiểu dữ liệu có dấu và không dấu được chỉ ra trong các gói chuẩn NUMERIC_BIT và NUMERIC_STD. Các đối tượng với kiểu có dấu và không dấu được hiểu như là các số nguyên binary không dấu và các đối tượng với kiểu có dấu và chúng được dịch như các nguyên bù hai.
Việc định nghĩa của các kiểu dữ liệu được chỉ ra như sau:
type signed is array (NATURAL range <>) of BIT/STD_LOGIC;
Các phát biểu dưới đây bao gồm các khai báo việc sử dụng của các kiểu dữ kiểu có dấu và không dấu.
Library IEEE;
use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_BIT.all; use IEEE.NUMERIC_STD.all;
3.3.8. Các kiểu con
VHDL cung cấp các các kiểu con mà các kiểu con này chúng được định nghĩa trong các tập phụ trong một kiểu khác. Bất cứ ở đâu có một khai báo kiểu thì ở đó có thể xuất hiện một định nghĩa kiểu con. Kiểu NATURAL và kiểu POSITIVE là một kiểu phụ hay kiểu con của kiểu nguyên và chúng có thể được dùng với bất kỳ một hàm nguyên nào.
Ví dụ:
subtype INT4 is INTEGER range 0 to 15;
3.4. CÁC TOÁN TỬ
VHDL cung cấp 7 lớp toán tử, mỗi một toán tử có một mức ưu tiên nhất định. Tất cả các toán tử trong cùng một lớp thì có cùng một mức ưu tiên khi được sử dụng trong cùng một biểu thức. Bảng 3.1 minh họa các toán tử trong VHDL. Bắt đầu từ đầu bảng, mỗi lớp toán tử có ưu tiên cao hơn nhóm tiếp theo.
Toán tử của VHDL Thao tác Các toán hạng Toán tử tạp not ** Abs NOT logic Hàm mũ
Giá trị tuyệt đối
Cùng kiểu Kiểu mũ Integer Bất kỳ kiểu số nào Toán tử nhân * / mod rem Nhân Chia Modulus Phần dư Cùng kiểu Cùng kiểu Integer Integer Toán tử dấu + - Đồng nhất Phủ định Bất kỳ kiểu số nào Bất kỳ kiểu số nào Toán tử cộng + - & Cộng Trừ Nối Cùng kiểu Cùng kiểu Toán tử dịch bit sll srl sla sra rol ror Dịch trái logic Dịch phải logic Dịch trái số học Dịch phải số học Quay trái logic Quay phải logic
Số bit dịch kiểu Integer Số bit dịch kiểu Integer Số bit dịch kiểu Integer Số bit dịch kiểu Integer Số bit dịch kiểu Integer Số bit dịch kiểu Integer Toán tử quan hệ
= /= < <= > >= Bằng Không bằng Nhỏ hơn Nhỏ hơn hoặc bằng Lớn hơn Lớn hơn hoặc bằng Cùng kiểu Cùng kiểu Cùng kiểu Cùng kiểu Cùng kiểu Cùng kiểu Toán tử Logic and or nand nor xor AND logic OR logic NAND logic NOR logic XOR logic Cùng kiểu Cùng kiểu Cùng kiểu Cùng kiểu Cùng kiểu Bảng 3.1: Các loại toán tử. 3.4.1. Các toán tử Logical
Các toán hạng cần phải là cùng kiểu và cùng độ dài.
Ví dụ:
signal A,B : BIT_VECTOR (6 downto 0); signal C,D,E,F,G: BIT;
A <= B and C ; -- Không xảy ra vì các toán hạng không cùng kiểu. D <= (E xor F) and (C xor G);
3.4.2. Các toán tử quan hệ
Các toán tử quan hệ cho ta kết quả có kiểu Boolean, các toán hạng cần phải có cùng kiểu và cùng độ dài.
Ví dụ:
signal A,B : BIT_VECTOR (6 downto 0); signal C: BOOLEAN;
C <= B <= A; -- Tương đương như C <= (B<=A);
3.4.3. Các toán tử dịch bit
Các toán tử dịch bit yêu cầu hai toán hạng. Toán hạng trước toán tử là toán hạng chứa dữ liệu để được dịch bit, còn toán hạng sau toán tử là toán hạng chứa số thao tác dịch bit được thực hiện (nghĩa là số bit được dịch).
Ví dụ:
entity SHIFT is
Y1,Y2,Y3,Y4,Y5,Y6: out UNSIGNED (7 downto 0); end entity SHIFT;
architecture LOGIC of SHIFT is constant B: integer :=3; begin process (A,B) begin Y1 <= A sll B; --Dịch trái logic Y2 <= A srl B ; --Dịch phải logic Y3 <= A rol B ; --Quay trái logic Y4 <= A ror B ; --Quay phải logic Y5 <= A sla B ; --Dịch trái số học Y6 <= A sra B ; --Dịch phải số học end process ;
end architecture LOGIC ;
3.4.4. Các toán tử cộng
Các toán tử cộng bao gồm "+", "-" , và "&", trong đó toán tử "&" là toán tử kết nối chuỗi và các đối tượng là mảng các thanh ghi. Với số có dấu và không dấu có thể được dùng với các số nguyên và các kiểu BIT_VECTOR.
Ví dụ:
signal W: BIT_VECTOR (3 downto 0); signal X: INTEGER range 0 to15; signal Y,Z : UNSIGED (3 downto 0); Z <= X + Y + Z;
Y <= Z (2 downto 0) & W(1);
"ABC" & "xyz" cho kết quả là : "ABCxyz" "1010" & "1" cho kết quả là : "10101"
3.5. CÁC KIỂU TOÁN HẠNG
Trong một biểu thức các toán tử sử dụng các toán hạng để tính toán các giá trị của chúng. Các toán hạng trong một biểu thức bao gồm :
- Kiểu chữ. - Kiểu định danh.
- Các tên được đánh theo chỉ số. - Tên các Slice.
- Tên các đặc tính. - Kiểu tập hợp.
- Các biểu thức gán kiểu. - Các biểu thức chuyển đổi. - Các lời gọi hàm.
3.5.1. Kiểu chữ
Các kiểu chữ có thể chia ra thành hai nhóm chính : Kiểu vô hướng:
- Kiểu chữ ký tự - Kiểu BIT
- Kiểu chuẩn STD_LOGIC - Kiểu Boolean
- Kiểu số thực - Kiểu nguyên - Kiểu thời gian Kiểu mảng:
- Kiểu chuỗi
- Kiểu BIT_VECTOR - STD_LOGIC_VECTOR
3.5.1.1. Kiểu chữ ký tự
Kiểu chữ ký tự chỉ ra một giá trị bằng việc sử dụng một ký tự đơn và kèm theo một dấu nháy đơn. Nhìn chung VHDL không quan tâm đến các trường hợp chữ thường và chữ hoa, xong với kiểu chữ ký tự cần phải phân biệt chữ thường và chữ hoa. Ví dụ: 'a' hoàn toàn khác với kiểu 'A' trong kiểu chữ ký tự. Kiểu chữ ký tự có thể được dùng để định nghĩa bất cứ kiểu nào trong các đóng gói chuẩn và giá trị mặc định của chúng là Null.
Ví dụ: 'A' , 'a' , ...'1' .
Kiểu chữ ký tự không phải là kiểu bit ký tự như '1' hoặc kiểu nguyên 1, vì vậy kiểu chữ ký tự cần phải được cung cấp một tên kiểu nào đó.
3.5.1.2. Kiểu chuỗi
Một kiểu chuỗi ký tự thực chất là một mảng các ký tự. Một chuỗi các ký tự được định nghĩa trong một dấu nháy kép.
3.5.1.3. Kiểu BIT
Kiểu bit là kiểu mô tả hai giá trị rời rạc bằng việc sử dụng các chữ ký tự '0' và '1'. Đôi khi các kiểu Bit này được dùng để tạo ra kiểu chữ bit một cách tường minh dùng để phân biệt chúng với các kiểu ký tự.
Ví dụ: '1' , ' 0 ' , bit('1')
3.5.1.4. Kiểu BIT_VECTOR
Kiểu bit_vector là một mảng các bit mà chúng được đặt trong dấu nháy kép.
Ví dụ: "01001111000" , x"00FFF0" , b"100010101" , o"277756"...
Trong ví dụ trên chữ 'x' được dùng để diễn tả các giá trị số hexa, còn 'b' được dùng để mô tả kiểu binary, còn 'o' được dùng cho hệ đếm cơ số 8.