Tải bản đầy đủ (.doc) (68 trang)

Kiến thức cơ bản về VHDL

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (384.55 KB, 68 trang )

KIẾN THỨC CƠ BẢN VỀ VHDL
VHDL là viết tắt của cụm từ Very High Speed Intergrated Circuit Hardware
Description Language - ngôn ngữ mô tả phần cứng cho các mạch tích hợp tốc độ rất
cao. VHDL là ngôn ngữ mô tả phần cứng được phát triển dùng cho chương trình
VHSIC (Very High Speed Intergrated Circuit) của bộ quốc phòng Mỹ. Mục tiêu của
việc phát triển VHDL là có được một ngôn ngữ mô tả phần cứng tiêu chuẩn và
thống nhất cho phép phát triển thử nghiệm các hệ thống số nhanh hơn cũng như cho
phép dễ dàng đưa các hệ thống đó vào ứng dụng trong thực tế. Ngôn ngữ VHDL
được ba công ty Intermetics, IBM và Texas Instruments bắt đầu nghiên cứu phát
triển vào 7/1983. Phiên bản đầu tiên được công bố vào 8/1985. Sau đó VHDL được
đề xuất để tổ chức IEEE xem xét thành một tiêu chuẩn. Năm 1987, đã đưa ra tiêu
chuẩn về VHDL – tiêu chuẩn IEEE-1076-1987.
VHDL được phát triển để giải quyết các khó khăn trong việc phát triển, thay đổi
và lập tài liệu cho các hệ thống số. Như ta đã biết, một hệ thống số có rất nhiều tài
liệu mô tả. Ðể có thể vận hành bảo trì sửa chữa một hệ thống ta cần tìm hiểu tài liệu
đó kỹ lưỡng. Với một ngôn ngữ mô tả phần cứng thì việc xem xét các tài liệu mô tả
trở nên dễ dàng hơn vì bộ tài liệu đó có thể được thực thi để mô phỏng hoạt động
của hệ thống. Như thế ta có thể xem xét toàn bộ các phần tử của hệ thống hoạt động
trong một mô hình thống nhất.
Trước khi VHDL ra đời, có nhiều ngôn ngữ mô tả phần cứng được sử dụng
nhưng không có một tiêu chuẩn thống nhất. Vì các ngôn ngữ mô phỏng phần cứng
đó được các nhà cung cấp thiết bị phát triển, nên mang các đặc trưng gắn với các
thiết bị của nhà cung cấp đó và thuộc sở hữu của nhà cung cấp.
Trong khi đó, VHDL được phát triển như một ngôn ngữ độc lập không gắn với
bất kỳ một phương pháp thiết kế, bộ mô phỏng hay công nghệ phần cứng nào.
Người thiết kế có thể tự do lựa chọn công nghệ, phương pháp thiết kế trong khi vẫn
sử dụng một ngôn ngữ duy nhất.
VHDL có một số ưu điểm hơn hẳn các ngôn ngữ mô tả phần cứng khác là:
• Tính công cộng: VHDL được phát triển dưới sự bảo trợ của chính phủ Mỹ
và hiện nay là một tiêu chuẩn của IEEE, VHDL không thuộc sở hữu của bất
kỳ cá nhân hay tổ chức nào. Do đó VHDL được hỗ trợ của nhiều nhà sản


1
xuất thiết bị cũng như nhiều nhà cung cấp công cụ thiết kế mô phỏng hệ
thống. Ðây là một ưu điểm nổi bật của VHDL, giúp VHDL trở nên ngày
càng phổ biến.
• Khả năng hỗ trợ nhiều công nghệ và phương pháp thiết kế: VHDL cho
phép thiết kế bằng nhiều phương pháp như phương pháp thiết kế từ trên
xuống, hay từ dưới lên dựa vào các thư viện có sẵn. Như vậy VHDL có thể
phục vụ tốt cho nhiều mục đích thiết kế khác nhau, từ việc thiết kế các phần
tử phổ biến đến việc thiết kế các IC ứng dụng đặc biệt (Application Specified
IC).
• Ðộc lập với công nghệ: VHDL hoàn toàn độc lập với công nghệ chế tạo
phần cứng. Một mô tả hệ thống dùng VHDL thiết kế ở mức cổng có thể
được chuyển thành các bản tổng hợp mạch khác nhau tuỳ thuộc vào công
nghệ chế tạo phần cứng nào được sử dụng (dùng CMOS, nMOS, hay GaAs).
Ðây cũng là một ưu điểm quan trọng của VHDL nó cho phép người thiết kế
không cần quan tâm đến công nghệ phần cứng khi thiết kế hệ thống, như thế
khi có một công nghệ chế tạo phần cứng mới ra đời nó có thể được áp dụng
ngay cho các hệ thống đã thiết kế.
• Khả năng mô tả mở rộng: VHDL cho phép mô tả hoạt động của phần cứng
từ mức hệ thống số (hộp đen) cho đến mức cổng. VHDL có khả năng mô tả
hoạt động của hệ thống trên nhiều mức nhưng chỉ sử dụng một cú pháp chặt
chẽ thống nhất cho mọi mức. Như thế ta có thể mô phỏng một bản thiết kế
bao gồm cả các hệ con được mô tả ở mức cao và các hệ con được mô tả chi
tiết.
• Khả năng trao đổi kết quả: Vì VHDL là một tiêu chuẩn được chấp nhận,
nên một mô hình VHDL có thể chạy trên mọi bộ mô phỏng đáp ứng được
tiêu chuẩn VHDL và các kết quả mô tả hệ thống có thể được trao đổi giữa
các nhà thiết kế sử dụng công cụ thiết kế khác nhau nhưng cùng tuân theo
chuẩn VHDL. Hơn nữa, một nhóm thiết kế có thể trao đổi mô tả mức cao
của các hệ thống con trong một hệ thống; trong khi các hệ con đó được thiết

kế độc lập.
• Khả năng hỗ trợ thiết kế mức lớn và khả năng sử dụng lại các thiết kế:
VHDL được phát triển như một ngôn ngữ lập trình bậc cao, vì vậy nó có thể
sử dụng để thiết kế một hệ thống lớn với sự tham gia của một nhóm nhiều
2
người. Bên trong ngôn ngữ VHDL có nhiều tính năng hỗ trợ việc quản lý,
thử nghiệm và chia sẻ thiết kế. VHDL cũng cho phép dùng lại các phần đã có
sẵn.
3.1. CÁC CẤU TRÚC CƠ BẢN CỦA NGÔN NGỮ VHDL
Các thành phần chính xây dựng trong ngôn ngữ VHDL được chia ra thành năm
nhóm cơ bản như sau:
- Entity
- Architecture
- Package
- Configuration.
- Library.
Entity: Trong một hệ thống số, thông thường được thiết kế theo một sự xếp chồng
các Modul, mà mỗi Modul này tương ứng với một thực thể thiết kế (được gọi là
Entity) trong VHDL. Mỗi một Entity bao gồm hai phần:
- Khai báo thực thể ( Entity).
- Thân kiến trúc ( Architecture Bodies )
Một khai báo Entity được dùng để mô tả giao tiếp bên ngoài của một phần tử
(component), nó bao gồm các khai báo các cổng đầu vào, các cổng đầu ra của phần
tử đó. Phần thân của kiến trúc được dùng để mô tả sự thực hiện bên trong của thực
thể đó.
Packages: Các đóng gói chỉ ra thông tin dùng chung, mà các thông tin này được sử
dụng bởi một vài Entity nào đó.
Configuration: Định cấu hình, nó cho phép gắn kết các thể hiện của phần tử cần
dùng nào đó của một thiết kế nào đó có dạng một cấu trúc và đưa các thể hiện này
vào trong cặp Entity và Architecture.

Nó cho phép người thiết kế có thể thử nghiệm để thay đổi các sự thực thi khác nhau
trong một thiết kế. Mỗi một thiết kế dạng VHDL bao gồm một vài đơn vị thư viện,
mà một trong các thư viện này được dịch sẵn và cất trong một thư viện thiết kế.
3
3.1.1. Khai báo Entity
Như trên đã đề cập, phần khai báo Entity chỉ đưa ra một cái nhìn phía bên ngoài của
một phần tử mà không cung cấp thông tin về sự thực hiện của phần tử đó như thế
nào. Cú pháp khai báo của một Entity như sau:
Entity entity_name is
[generic (generic_declaration);]
[port (port_declaration);]
{entity_declarative_item {constants, types, signals};}
end [entity_name];
• [] : Dấu ngoặc vuông chỉ ra các tham số có thể lựa chọn.
• | : Dấu gạch đứng hiển thị một sự lựa chọn trong số các lựa chọn khác.
• {} : Khai báo một hoặc nhiều các đối tượng, mà các đối tượng này có thể
được định nghĩa bởi người dùng.
a. Khai báo Generic: Dùng để khai báo các hằng mà chúng có thể được dùng để
điều khiển cấu trúc và sự hoạt động của Entity. Cú pháp của khai báo này như sau:
generic ( constant_name : type [:=init_value]
{;constant_name: type[:=init_value]});
• Ở đây tên hằng constant_name chỉ ra tên của một hằng dạng generic (hằng
dùng chung).
• Kiểu (Type) được dùng để chỉ ra kiểu dữ liệu của hằng.
• Init_value : chỉ ra giá trị khởi tạo cho hằng.
b. Khai báo cổng ( Port ): Được dùng để khai báo các cổng vào, ra của Entity. Cú
pháp của khai báo này như sau:
Port ( port_name : [mode] type [:= init_value]
{; port_name:[mode] type [:=init_value]});
• Port_name được dùng để chỉ ra tên của một cổng, mode chỉ ra hướng vào ra

của tín hiệu tại cổng đó. Type chỉ ra kiểu dữ liệu của một cổng và init_value
chỉ ra giá trị khởi tạo cho cổng đó.
Chú ý ! Với VHDL không phân biệt chữ hoa và chữ thường, chẳng hạn như: xyz =
xYz = XYZ.
• Có bốn mode được sử dụng trong khai báo cổng:
4
- in: Chỉ có thể được đọc, nó chỉ được dùng cho các tín hiệu đầu vào (chỉ
được phép nằm bên phải phép gán).
- out: Chỉ được dùng để gán giá trị, nó chỉ được dùng cho các cổng đầu ra
(nó chỉ được nằm bên trái của phép gán).
- inout: Có thể được dùng để đọc và gán giá trị. Nó có thể có nhiều hơn một
hướng điều khiển (có thể nằm ở bên trái hoặc bên phải phép gán).
- Buffer: Có thể được dùng để đọc và gán giá trị (có thể nằm ở bên trái hoặc
bên phải phép gán). Inout là một cổng hai hướng, còn Buffer là một cổng
không có hướng.
c. Entity_declarative_item : Được dùng để khai báo các hằng, kiểu dữ liệu, hoặc
tín hiệu mà nó có thể được sử dụng trong khi thực hiện của một Entity.
d. Ví dụ :
Ví dụ về khai báo các cổng vào ra:
entity xxx is
port ( A : in integer ;
B : in integer ;
C : out integer ;
D : inout integer ;
E : buffer integer) ;
end xxx;
architecture bhv of xxx is
begin
process (A,B)
begin

C <= A ; -- ( Câu lệnh đúng: A được gán cho C ).
A <= B ; -- ( Câu lệnh sai: A là một đầu vào ).
E <= D + 1; -- ( Câu lệnh đúng: D ở mode inout vì vậy nó
-- có thể được gán và đọc )
D <= C + 1; -- ( Câu lệnh sai : C là cổng đầu ra nên không
-- thể đọc được cho đầu vào ).
end process;
end bhv;
Ví dụ về khai báo Entity:
5
Hình 3.1: Thực thể FULL_ADDER 1bit.
Hình 3.1 chỉ ra một giao diện của một bộ cộng một bit. Tên Entity của phần tử này
là FULL_ADDER. Nó bao gồm các cổng đầu vào A, B và CIN.
Các cổng này có kiểu dữ liệu là kiểu Bit, còn các cổng đầu ra SUM và COUT cũng
mang kiểu dữ liệu là kiểu BIT. Ngôn ngữ VHDL dùng để diễn tả giao diện này như
sau:
Entity FULL_ADDER is
port ( A, B, CIN : in BIT;
SUM, COUT : out BIT );
End FULL_ADDER ;
Chúng ta có thể điều khiển cấu trúc cũng như thời gian của một Entity bởi việc sử
dụng các hằng generic. Ví dụ sau sẽ chỉ ra việc điều khiển này, trong ví dụ này hằng
N được dùng để chỉ ra số bít của một bộ cộng. Trong quá trình mô phỏng hoặc quá
trình tổng hợp, giá trị thực tế cho mỗi hằng dùng chung generic có thể bị thay đổi.
entity ADDER is
generic (N : INTEGER := 4);
M : TIME := 10ns);
port ( A, B : in BIT_VECTOR (N -1 downto 0 );
CIN :in BIT;
SUM : out BIT_VECTOR (N-1 downto 0);

COUT : out BIT );
end ADDER;
Giao diện mô tả bộ cộng này như sau:
6
Hình 3.2: Thực thể FULL_ADDER 4 bit.
3.1.2. Các kiểu kiến trúc (Achitecture)
Một kiến trúc đưa ra kết cấu bên trong của một Entity. Một Entity có thể có nhiều
hơn một kiến trúc, nó chỉ ra quan hệ giữa các đầu vào và đầu ra của một Entity mà
quan hệ này được diễn tả theo các thuật ngữ sau:
- Kiểu hành vi hoạt động ( Behavioral ).
- Kiểu hoạt động của các luồng dữ liệu ( Dataflow ).
- Kiểu cấu trúc ( Structure ).
Một kiến trúc xác định chức năng của một Entity. Nó bao gồm các phần: Khai báo
các các tín hiệu, hằng, khai báo các kiểu, các phần tử, tiếp theo là các phát biểu
(lệnh) đồng thời.
Khai báo một kiến trúc sử dụng cú pháp sau:
architecture architecture_name of entity_name is
{ architecture_declarative_part }
Begin
{concurrent_statement} --(lệnh đồng thời)
end [ architecture_name ];
3.1.2.1. Kiến trúc theo kiểu hành vi hoạt động (Behavioral)
Một kiến trúc kiểu hành vi hoạt động chỉ ra các hoạt động mà một hệ thống riêng
biệt nào đó phải thực hiện trong một chương trình, nó giống như việc diễn tả các
quá trình hoạt động, nhưng không cung cấp chi tiết mà thiết kế được thực thi như
thế nào. Thành phần chủ yếu của việc diễn tả theo kiểu hành vi trong VHDL là
7
process. Dưới đây là ví dụ chỉ ra kiểu diễn tả theo kiểu hành vi của một bộ cộng với
tên là FULL_ADDER.
architecture BEHAVIOUR of FULL_ADDER is

begin
process (A,B,CIN)
begin
if ( A ='0' and B ='0' and CIN='0' ) then
SUM <= '0';
COUT <= '0' ;
elsif
(A='0' and B='0' and CIN='1') or
(A='0' and B='1' and CIN='0') or
(A='1' and B='0' and CIN='0') then
SUM <= '1';
COUT <= '0' ;
elsif
(A='0' and B='1' and CIN='1') or
(A='1' and B='0' and CIN='1') or
(A='1' and B='1' and CIN='0') then
SUM <= '0';
COUT <= '1';
elsif (A='1' and B='1' and CIN='1') then
SUM <='1';
COUT <='1';
end if;
end process;
end BEHAVIOURAL;
3.1.2.2. Kiến trúc theo kiểu hoạt động của các luồng dữ liệu (Dataflow)
Một kiến trúc kiểu luồng dữ liệu chỉ ra một hệ thống dưới dạng mô tả đồng thời của
các luồng điều khiển và dịch chuyển của dữ liệu. Nó sử dụng theo mẫu thông tin
hoặc mẫu hoạt động của luồng dữ liệu đó, hoặc mẫu thời gian của các chức năng
8
logic tổ hợp. Chẳng hạn như các bộ cộng, bộ so sánh, bộ giải mã, và các cổng logic

nguyên thủy.
Ví dụ:
architecture DATAFLOW of FULL_ADDER is
signal S : BIT;
begin
S <= A xor B ;
SUM <= S xor CIN after 10 ns;
COUT <= (A and B ) or (S and CIN) after 5ns;
end DATAFLOW;
3.1.2.2. Kiến trúc theo kiểu cấu trúc (Structure)
Một kiến trúc kiểu cấu trúc chỉ ra sự thực thi cấu trúc theo dạng sử dụng các khai
báo phần tử và các thể hiện của phần tử đó. Ví dụ dưới đây chỉ ra sự diễn tả cấu trúc
của một bộ cộng FULL_ADDER như trên đã giới thiệu.
Hai kiểu phần tử được sử dụng trong ví dụ này là HALF_ADDER và OR_GATE.
architecture STRUCTURE of FULL_ADDER is
component HALF_ADDER
port (L1, L2 : in BIT;
CARRY, SUM : out BIT);
end component;
component OR_GATE
port (L1, L2 : in BIT;
O: out BIT);
end component;
begin
HA1: HALF_ADDER port map (A,B,N1,N2);
HA2: HALF_ADDER port map (N2,CIN,N3,SUM);
OR1 : OR_GATE port map (N1, N3,COUT);
end STRUCTURE;
Ở ví dụ này Entity ở mức cao nhất sẽ chứa hai thể hiện của HALF_ADDER và một
thể hiện của OR_GATE. Thể hiện HALF_ADDER có thể bị rằng buộc với một

9
Entity khác, mà Entity này bao gồm một cổng XOR và một cổng AND. Giao tiếp
của một bộ cộng HALF_ADDER có dạng như sau:
Hình 3.3: Giao tiếp bộ cộng HALF_ADDER.
Bộ cộng này gồm có hai đầu vào L1 và L2, đầu ra là SUM và CARRY. Kiểu BIT là
kiểu tiền định nghĩa của ngôn ngữ VHDL, nó có kiểu liệt kê dạng chữ ký tự như '0'
và '1'.
3.1.3. Các đóng gói (Packages)
Mục đích chính của Package là tập hợp các phần tử có thể bị chia sẻ bởi hai hay
nhiều đơn vị thiết kế (hay các phần tử có thể dùng chung được). Nó có chứa các
kiểu dữ liệu, các hằng, các chương trình con có thể dùng chung giữa các thiết kế.
Một Package có cha hai phần chính:
- Phần khai báo Package.
- Phần thân Package.
3.1.3.1. Phần khai báo Package
Một khai báo Package được dùng để cất giữ hàng loạt các khai báo dùng chung,
chẳng hạn như các phần tử, các kiểu, các thủ tục, các hàm. Các khai báo này có thể
nhập vào các đơn vị thiết kế khác bởi việc sử dụng một mệnh đề use.
Ví dụ:
package EXAMPLE_PACK is
type SUMMER is ( MAY, JUN, JUL, AUG, SEP);
component D_FLIP_FLOP
port (D, CK:in BIT;
Q, QBAR: out BIT)
end component;
10
constant PIN2PIN_DELAY:TIME:=125ns;
function IN2BIT_VEC(INT_VALUE:INTEGER)
return BIT_VECTOR;
end EXAMPLE_PACK;

Ở ví dụ này tên của package được khai báo là EXAMPLE_PACK. Nó có chứa các
khai báo kiểu, phần tử, hằng, và hàm. Lưu ý rằng hoạt động của hàm
INT2BIT_VEC không xuất hiện ở trong khai báo gói, mà chỉ có giao tiếp của hàm
xuất hiện. Việc định nghĩa, hay thân của hàm chỉ xuất hiện trong thân của đóng gói
( Body Package ).
Giả sử rằng đóng gói này đã được dịch và tạo thành một thư viện thiết kế và được
gọi là DESIGN _LIB. Xem xét việc dùng mệnh đề use để sử dụng chúng dưới đây:
library DESIGN_LIB;
use DESIGN_LIB.EXAMPLE_PACK.all
Entity RX is.........
Mệnh đề library DESIGN_LIB cho phép thư viện thiết kế DESIGN_LIB được phép
dùng trong phần mô tả này, điều đó có nghĩa là tên DESIGN_LIB có thể được sử
dụng. Mệnh đề use tiếp theo sẽ lấy tất cả các khai báo có trong Package
EXAMPLE_PACK vào trong khai báo Entity của RX. Có nghĩa là ta có thể chọn
lựa các khai báo từ trong một các khai báo của một đóng gói vào trong một đơn vị
thiết kế khác.
Ví dụ :
library DESIGN_LIB;
use DESIGN_LIB.EXAMPLE_PACK.D_FLIP_FLOP;
use DESIGN_LIB.EXAMPLE_PACK.PIN2PIN_DELAY;
architecture RX_STRUCTURE of RX is.........
Hai mệnh đề use ở ví dụ này nhằm tạo ra khai báo cho D_FLIP_FLOP và khai báo
hằng cho PIN2PIN_DELAY được phép sử dụng trong thân kiến trúc.
3.1.3.1. Phần khai báo thân Package
Sự khác biệt giữa khai báo Package và thân Package có cùng mục đích như khai báo
của một Entity và phần thân kiến trúc Architecture của chúng. Cú pháp khai báo của
Package như sau:
package package_name is
11
{package_declarative_item}

end [package_name ];
package body package_name is
{package_declarative_item}
end [package_name]
Một thân package được dùng để lưu các định nghĩa của một hàm và thủ tục, mà các
hàm và thủ tục này chúng đã được khai báo trong phần khai báo package tương
ứng. Vì vậy phần thân package luôn được kết hợp với phần khai báo của chúng, hơn
nữa một phần khai báo package luôn có ít nhất một phần thân package kết hợp với
chúng.
Ví dụ:
package EX_PKG is
subtype INT8 is integer range 0 to 255;
constant zero : INT8:=0;
procedure Incrementer (variable Count : inout INT8);
end EX_PKG;
package body EX_PKG is
procedure Incrementer (variable Data : inout INT8) is
begin
if (Count >= MAX ) then
Count:=ZERO;
else Count:= Count +1;
end if;
end Incrementer;
end EX_PKG;
3.1.4. Định cấu hình (Configurations)
Mỗi một Entity bao gồm nhiều kiến trúc khác nhau. Trong quá trình thiết kế, người
thiết kế có thể muốn thử nghiệm với các sự biến đổi khác nhau của thiết kế bằng
việc chọn lựa các kiểu kiến trúc khác nhau. Configuration có thể được sử dụng để
cung cấp một sự thay thế nhanh các thể hiện của các phần tử (Component) trong
một thiết kế dạng cấu trúc. Cú pháp khai báo của Configuration này như sau:

Configuration configuration_name of entity_name is
12
{configuration_decalarative_part}
For block_specification
{use_cluse}
{configuration_item}
end for;
Với một Entity của bộ cộng FULL_ADDER như đã giới thiệu ở phần trên, ở ví dụ
này ta có thể sử dụng chúng trong phép định cấu hình như sau:
configuration FADD_CONFIG of FULL_ADDER is
For STRUCTURE
for HA1, HA2 : HALF_ADDER use entity
burcin.HALF_ADDER(structure);
for OR1: OR_GATE use Entity burcin.OR_GATE;
end for;
end FADD_CONFIG;
Ở đây tên của phép định cấu hình là tuỳ ý, ở ví dụ này ta lấy tên là
FADD_CONFIG, còn với dòng lệnh For STRUCTURE chỉ ra kiến trúc được định
cấu hình và được sử dụng với thực thể Entity FULL_ADDER. Giả sử rằng chúng ta
đã dịch hai thực thể HALF_ADDER và OR_GATE thành thư viện với tên là burcin
và sử dụng chúng trong ví dụ trên.
3.1.5. Các thư viện thiết kế
Kết quả của việc biên dịch VHDL là chúng được cất giữ bên trong các thư viện để
dùng cho bước mô phỏng tiếp theo, điều này giống như việc sử dụng một phần tử
đã được khai báo trong một thiết kế khác. Một thư viện thiết kế có thể chứa các đơn
vị thư viện như sau:
- Các đóng gói (PACKAGES)
- Các thực thể Entity
- Các kiểu kiến trúc Architectures
- Các phép định cấu hình Configurations.

Chú ý! VHDL không hỗ trợ các thư viện theo thứ bậc. Bạn có thể có nhiều thư viện
như theo ý muốn nhưng không được khai báo lồng nhau!
13
Để mở một thư viện và truy cập chúng như một Entity đã được biên dịch trong một
thiết kế VHDL mới, điều đầu tiên cần làm là phải khai báo tên thư viện. Cú pháp
của chúng như sau:
Library library_name : [path/directory_name];
Bạn có thể truy cập các đơn vị đã được biên dịch từ một thư viện VHDL tới ba mức
như sau:
library_name.Package_name.item_name
Ví dụ: Giả sử chúng ta tạo một đóng gói để cất một hằng mà hằng này được sử
dụng trong nhiều thiết kế, sau đó dịch nó và cất vào trong thư viện với tên là
burcin .
Package my_pkg is
constant delay: time:=10ns;
end my_pkg;
Tiếp đến chúng ta gọi my_pkg để sử dụng chúng trong thiết kế dưới đây:
architecture DATAFLOW of FULL_ADDER is
signal S : BIT;
begin
S <= A xor B;
SUM <= S xor CIN after burcin.my_pkg.delay;
COUT <= (A and B ) or (S and CIN) after 5ns;
end DATAFLOW;
3.2. CÁC ĐỐI TƯỢNG DỮ LIỆU
Một đối tượng dữ liệu giữ một giá trị của một kiểu nhất định. Trong VHDL có ba
lớp đối tượng dữ liệu :
- Các hằng (Constants).
- Các biến (Variables).
- Các tín hiệu (Signals).

Lớp cuả một đối tượng được chỉ ra bởi một từ khoá và nó được chỉ ra ở điểm bắt
đầu của một khai báo.
14
3.2.1. Các hằng (Constants)
Một hằng nó là một đối tượng mà nó được khởi tạo để chỉ ra một giá trị cố định và
nó 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 chú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];
Ví dụ:
15
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
chúng đượ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','_');
16
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.
17
- 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 SEVERITY_LEVEL is (note, warning, error, failure );
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ụ:
type A1 is array ( 0 to 31) of INTEGER;
type Bit_Vector is arrray (NATURAL range <>) of BIT;
18
type STRING is array (POSITIVE range <>) of CHARACTER;
A1 là một mảng gồm ba hai 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ụ:
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;
19
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 chúng đượ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
20
chúng đượ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 như 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;
subtype BIT_VECTOR6 is BIT_VECTOR (5 downto 0)
3.4. CÁC TOÁN TỬ
VHDL cung cấp 6 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.
Mức ưu
tiên
thấp
nhất
Các toán tử Các toán hạng
.
.
.
.
Logical_operator
and
or
nand
Cùng kiểu
Cùng kiểu
Cùng kiểu
21
Relational _ operator
nor
xor
=
/=

<
<=
>
>=
Cùng kiểu
Cùng kiểu
Cùng kiểu
Cùng kiểu
Cùng kiểu
Cùng kiểu
Cùng kiểu
Cùng kiểu
Concatenation_operator
arithmetic_operator
&
+
-
Cùng kiểu
Cùng kiểu
arithmetic_operator +
-
Bất kỳ kiểu số nào
Bất kỳ kiểu số nào
arithmetic_operator *
/
mod
rem
Cùng kiểu
Cùng kiểu
integer

integer
Mức ưu
tiên cao
nhất
arithmetic_operator
Logical_operator
**
abs
not
Kiểu mũ integer
Bất kỳ kiểu số nào
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);
22
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ử 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
- Các biểu thức điều kiện
- Các lời gọi hàm
- Các biểu thức chuyển đổi
23
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 .
Ví dụ: "A" , " hold time error ", " x " ....
24
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.
3.5.1.5. Kiểu chữ trong đóng gói chuẩn STD_LOGIC
Kiểu chữ logic chuẩn là một trong 9 giá trị được định nghĩa trong đóng gói chuẩn và
được đưa ra dưới dạng các chữ in hoa và đặt trong dấu ngoặc đơn.
Ví dụ:
' U ' không trùng với ' u '
' X ' , ' 0 ' , ' 1 ' , ' Z ' , ' W ' , ' L ' , ' H ' , ' _ '
3.5.1.6. Kiểu chữ STD_LOGIC_VECTOR
Một kiểu chữ STD_LOGIC_VECTOR thực chất là một mảng bao gồm các phần tử
của kiểu std_logic và được đặt trong dấu ngoặc kép.
Ví dụ: " 10_1Z" , " UUUUU " , signed("1011 ").....
3.5.1.7. Kiểu Boolean
Kiểu Boolean được dùng để mô tả hai giá trị rời rạc, đó là kiểu true và false.
Ví dụ: true , false , True , TRUE, FALSE ...
3.5.1.8. Kiểu số thực
Kiểu số thực là kiểu được dùng để diễn tả các số thực nằm trong khoảng từ
-1.0E+38 đến +1.0E+38.
Một kiểu số học có thể là kiểu dương hoặc âm nhưng chúng phải có dấu chấm thập
phân.
Ví dụ:+ 1.0 không được viết '1' hoặc 1 hoặc ' 1.0 '
25

×