Kien Thuc Co Ban VHDL

90
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 1

Transcript of Kien Thuc Co Ban VHDL

Page 1: Kien Thuc Co Ban VHDL

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

Page 2: Kien Thuc Co Ban VHDL

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

2

Page 3: Kien Thuc Co Ban VHDL

nhiều 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

Page 4: Kien Thuc Co Ban VHDL

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:

- 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).

4

Page 5: Kien Thuc Co Ban VHDL

- 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

Page 6: Kien Thuc Co Ban VHDL

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;

6

Page 7: Kien Thuc Co Ban VHDL

Giao diện mô tả bộ cộng này như sau:

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

Page 8: Kien Thuc Co Ban VHDL

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

8

Page 9: Kien Thuc Co Ban VHDL

năng 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

9

Page 10: Kien Thuc Co Ban VHDL

một 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

Page 11: Kien Thuc Co Ban VHDL

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:

11

Page 12: Kien Thuc Co Ban VHDL

package package_name is

{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ử

12

Page 13: Kien Thuc Co Ban VHDL

(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

{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.

13

Page 14: Kien Thuc Co Ban VHDL

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!

Để 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

Page 15: Kien Thuc Co Ban VHDL

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

Page 16: Kien Thuc Co Ban VHDL

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);

16

Page 17: Kien Thuc Co Ban VHDL

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.

17

Page 18: Kien Thuc Co Ban VHDL

- 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 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;

18

Page 19: Kien Thuc Co Ban VHDL

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 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

19

Page 20: Kien Thuc Co Ban VHDL

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;

20

Page 21: Kien Thuc Co Ban VHDL

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 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

21

Page 22: Kien Thuc Co Ban VHDL

.

.

.

.

.

.

.

.

.

.

Logical_operator

and

or

nand

Cùng kiểu

Cùng kiểu

Cùng kiểu

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ụ:

22

Page 23: Kien Thuc Co Ban VHDL

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ử 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

23

Page 24: Kien Thuc Co Ban VHDL

- 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

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

Page 25: Kien Thuc Co Ban VHDL

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

Page 26: Kien Thuc Co Ban VHDL

0.0 không được viết 0

-1.0 , -1.0E+10.

3.5.1.9. Kiểu nguyên

Một kiểu nguyên được dùng để diễn tả các số nguyên nằm trong khoảng từ -

2,147,438,647 đến + 2,147,438,647.

Ví dụ: +1,862; - 257 ; + 123; - 456 ; 16 # 00FF #.

Trong đó các ký hiệu được dùng để định nghĩa kiểu như sau: "Cơ số n # số diễn tả

trong cơ số n đó", ở đây n nằm trong hệ 2 đến 16.

3.5.1.2. Kiểu TIME

Một kiểu vật lý duy nhất được định nghĩa trước trong đóng gói chuẩn, đó là thời

gian time.

Ví dụ: 10 ns , 100 us , 6.3 ns .....

Chú ý phần số phải được viết cách phần đơn vị đo bởi một khoảng trống.

3.5.2. Các kiểu định danh

Kiểu định danh đơn thuần chỉ là một cái tên do người dùng định nghĩa, nó có thể

là tên của một hằng, một biến hay một tín hiệu, một Entity, một cổng, hay một

chương trình con, hay các khai báo tham biến. Khi khai báo một tên cần phải khai

báo ký tự đầu tiên phải kiểu chữ ký tự, lưu ý dấu gạch dưới không được phép đứng

sau cùng, các từ khoá của VHDL không được dùng để làm khai báo các kiểu định

danh, chẳng hạn như entity, port ....

Ví dụ: xyz = xYZ = XYZ = XyZ

S(3) phần tử thứ ba của mảng S

X3.

3.5.3. Kiểu INDEX

Kiểu INDEX được sử dụng để chỉ ra một phần tử nào đó trong một mảng.

Cú pháp sử dụng của khai báo này như sau:

array_name (expression)

Với array_name là một tên của một hằng hay một biến nào đó nằm trong một

mảng. Còn expression phải trả về giá trị nằm trong dải chỉ số của mảng đó.

Ví dụ:

26

Page 27: Kien Thuc Co Ban VHDL

type memory is array ( 0 to 7 ) of INTEGER range 0 to 123;

variable DATA_ARRAY : memory;

variable ADDR : INTEGER range 0 to 7;

variable DATA: INTEGER range 0 to 123;

DATA:= DATA_ARRAY ( ADDR );

3.5.4. Kiểu Slice và ALIAS

Một khai báo Slice được dùng để chỉ ra một số phần tử của mảng. Hướng của nó

cần phải phù hợp với hướng mảng. Alias được dùng để tạo ra một tên mới cho tất

cả các phần tử hoặc một số phần tử nào đó nằm trong một mảng.

Ví dụ:

variable A1: BIT_VECTOR ( 7 downto 0 );

A2: = A1(5 downto 2) ;

Alias A3: BIT_VECTOR (0 to 3) is A1(7 downto 4);

--Có nghĩa là A3(0)=A1(7), A3(1)=A1(6), A3(2)=A1(5), A3(3)= A1(4)

Alias A4: BIT is A1(3);

3.5.5. Kiểu thuộc tính ATTRIBUTE

Lấy các thuộc tính cuả một biến hay một tín hiệu của một kiểu cho trước nào đó và

trả về một kiểu giá trị. Dưới đây là các kiểu thuộc tính thường dùng trong ngôn

ngữ VHDL:

- Left: Trả về chỉ số của phần tử ở bên trái cùng của một kiểu dữ liệu.

- Right: Trả về chỉ số của phần tử ở bên phải cùng của một kiểu dữ liệu.

- High: Trả về chỉ số của phần tử cao nhất của một kiểu dữ liệu.

- Low: Trả về chỉ số của phần tử thấp nhất của một kiểu dữ liệu.

- Range: Được dùng để lấy về dải của chỉ số.

- Reverse_range: Dùng để xác định dải chỉ số ngược lại.

- Length: Trả về số phần tử của kiểu BIT_VECTOR.

- Event: Mô tả sự thay đổi giá trị của tín hiệu tại thời điểm mô phỏng.

Ví dụ:

variable A1 : BIT_VECTOR ( 10 downto 0 );

A1' left -- Trả về giá trị là 10.

A1' right -- Trả về giá trị 0.

A1' high -- Trả về giá trị là 10.

27

Page 28: Kien Thuc Co Ban VHDL

A1' low -- Trả về giá trị là 0.

A1' range -- Trả về là 10 downto 0.

A1' reverse_range -- Trả về giá trị là 0 to 10.

A1' length -- Trả về giá trị là 11.

3.5.6. Kiểu tập hợp

Kiểu tập hợp có thể được dùng để gán giá trị cho một đối tượng thuộc kiểu mảng

hoặc kiểu Record trong khi khởi tạo khai báo hoặc trong các phát biểu gán.

Ví dụ:

type color_list ( red, orange, blue, white );

type color_array is array (color_list) of BIT_VECTOR ( 1 downto 0 );

variable X : color_array;

X := (" 00 " , " 01 " , " 10 " ," 11 " );

X := ( red => "00" , blue => "01" , orange => "10" , white => "11" );

Trong dòng thứ hai, chúng ta định nghĩa một mảng mà số các phần tử của chúng

(dải chỉ số) được đưa ra bởi color_list. Từ color_list chúng ta có một mảng gồm

bốn phần tử và mảng color_array cũng sẽ bao gồm bốn phần tử, mà mỗi phần tử

này lại được định nghĩa bởi kiểu Bit_Vector. Hơn nữa, chúng ta sử dụng dải chỉ số

của mảng color_list sẽ có dải từ 0 đến 3, vì việc định nghĩa của mảng này chỉ chỉ

ra dải chỉ số chứ không chỉ ra kiểu của phần tử trong mảng.

3.5.7. Biểu thức gán kiểu

Biểu thức gán kiểu được dùng để chỉ ra kiểu của một toán hạng nào đó.

Cú pháp của chúng như sau:

type_name' ( expression );

Ví dụ:

type color1 is (red, orange, blue, white);

type color2 is (purple, green, red, black);

color2'(red);

Như chúng ta thấy toán hạng red có cả trong hai kiểu color1 và color2, vì vậy nó

cần phải được gán một kiểu dữ liệu rõ ràng và điều này được thực hiện bởi câu

lệnh thứ 3.

28

Page 29: Kien Thuc Co Ban VHDL

3.5.8. Phép chuyển đổi kiểu tín hiệu

Phép chuyển đổi kiểu cho phép chuyển đổi các kiểu có kiểu dữ liệu gần giống

nhau.

Ví dụ:

signal X : STD_LOGIC_VECTOR ( 3 downto 0 );

signal Y : STD_ULOGIC_VECTOR ( 3 downto 0 );

Y <= STD_ULOGIC_VECTOR (X);

Sau câu lệnh thứ ba Y sẽ nhận kiểu STD_ULOGIC_VECTOR.

3.6. CÁC PHÁT BIỂU TUẦN TỰ

Phát biểu tuần tự chỉ ra sự thực hiện từng bước của một quá trình. Chúng thực hiện

từ câu lệnh đầu tiên, câu lệnh thứ hai, ... câu lệnh cuối cùng. Các phát biểu nằm

trong một phát biểu quá trình (phát biểu Process) được gọi là phát biểu tuần tự.

Các phát biểu sau đây là các phát biểu tuần tự được định nghĩa trong VHDL:

- Các phát biểu gán biến Variable.

- Các phát biểu gán tín hiệu Signal.

- Các phát biểu If.

- Các phát biểu Case.

- Các phát biểu Null.

- Các phát biểu xác nhận Assertion.

- Các phát biểu vòng lặp Loop.

- Các phát biểu Next.

- Các phát biểu Exit.

- Các phát biểu Wait.

- Các phát biểu Procedure.

- Các phát biểu Return.

3.6.1. Phát biểu gán biến

Dùng để thay thế giá trị hiện thời của biến với một giá trị mới, giá trị mới này

được chỉ ra bởi một biểu thức. Biến có thể được khai báo và sử dụng bên trong

một phát biểu quá trình hay còn được gọi là phát biểu Process. Một biến được gán

một giá trị sử dụng thông qua phát biểu gán biến, mà phát biểu này có hình thức

như sau:

29

Page 30: Kien Thuc Co Ban VHDL

target_variable : = expression;

Lưu ý, các biến được khai báo trong một Process không thể chuyển giá trị ra ngoài

Process, điều đó có nghĩa là chúng chỉ được cấp phát trong Process hoặc trong

chương trình con.

Ví dụ về phép gán biến trong một Process.

process (C,D)

variable Av, Bv, Ev : integer := 0;

begin

Av := 2;

Bv := Av + C;

Ev := Av * 2;

A <= Av;

B <= Bv;

E <= Cv;

end process;

A = 3 A <= 3 Av = 3

B = 3 B <= 3 Bv = 3

C = 1

D = 2

E = 6 E = 6 Ev = 6

Biểu thức được xác định giá trị khi phát biểu được thực thi và giá trị được tính

toán sẽ được gán cho biến một cách tức thời. Biến được tạo tại thời điểm sản sinh

và duy trì giá trị của nó trong suốt thời gian chạy chương trình. Do vì một quá

trình không bao giờ được thoát ra trong mỗi trạng thái hoạt động của nó, nghĩa là

chúng được thực thi, hoặc ở trong một trạng thái chờ. Nếu ở trạng thái chờ thì

chúng phải chờ cho đến khi một sự kiện khác chắc chắn xảy ra. Một quá trình bắt

đầu thực hiện tại điểm khởi đầu của một quá trình mô phỏng, tại thời điểm này nó

được thực thi cho đến khi gặp một phát biểu wait hoặc gặp các thành phần được

khai báo trong danh mục cần được xử lý khai báo trong Process.

Xem thí dụ về phát biểu Process như sau:

Ví dụ 1:

process(A)

variable EVENT_ON_A : INTEGER : = -1;

30

Page 31: Kien Thuc Co Ban VHDL

begin

EVENT_ON_A : = EVENT_ON_A +1;

end process;

Ví dụ 2:

Subtype INT16 is INTEGER range 0 to 65536;

Signal S1, S2 : INT16;

Signal GT : BOOLEAN;

process (S1, S2)

variable A, B : INT6;

constant C : INT16 : = 100;

Begin

A := S1 +1 ;

B : = S2*2 - C;

GT <= A > B;

End Process;

Tại lúc bắt đầu của quá trình mô phỏng. Quá trình được thực thi một lần. Biến

EVENT_ON_A được gán giá trị -1 sau đó tăng lên 1. Sau đó, thời điểm bất kỳ

xảy ra, sự kiện trên tín hiệu A, quá trình có hiệu lực và phát biểu gán biến đơn

được thực thi. Nó làm cho biến EVENT_ON_A tăng lên một. Tại thời điểm kết

thúc của quá trình mô phỏng, biến EVENT_ON_A chứa tổng số sự kiện xảy ra

trên tín hiệu A.

Một thí dụ khác của phát biểu quá trình :

signal A, Z:INTEGER;

. . .

PZ: process(A); -- PZ là nhãn của quá trình

variable V1,V2 : INTEGER;

begin

V1:=A-V2; -- statement 1

Z<= -V1; -- statement 2

V2:= Z+V1*2; -- statement 3

end process PZ;

Giả sử một sự kiện xảy ra trên tín hiệu A tại thời điểm T1 và biến V2 được gán giá

trị là 10, trong phát biểu thứ 3, sau đó một sự kiện xảy ra trên tín hiệu A tại thời

31

Page 32: Kien Thuc Co Ban VHDL

điểm T2, giá trị của V2 được sử dụng trong phát biểu 1 sẽ cũng là 10. Một biến

cũng có thể được khai báo bên ngoài một quá trình hoặc một chương trình con.

Một biến có thể được đọc và cập nhật bởi một hoặc có thể nhiều quá trình, những

biến này được gọi là shared variable (biến chia sẻ).

3.6.2. Phát biểu gán tín hiệu

Phát biểu gán tín hiệu sẽ thay thế giá trị hiện tại của tín hiệu với một giá trị mới

bởi việc sử dụng một biểu thức. Tín hiệu và kết quả của biểu thức cần có cùng một

kiểu dữ liệu.

Cú pháp của chúng như sau:

target_signal <= [ Transport] expression [after time_expression]

Phát biểu gán tín hiệu có thể xuất hiện bên trong hoặc bên ngoài một quá trình.

Nếu nó xảy ra bên ngoài của một quá trình, nó được xem là một phát biểu gán tín

hiệu đồng thời. Khi phát biểu gán tín hiệu xuất hiện bên trong quá trình, nó được

xem như là một phát biểu gán tín hiệu có thứ tự và nó được thực thi tuần tự theo

thứ tự của những phát biểu tuần tự khác xuất hiện bên trong quá trình.

Ví dụ phép gán tín hiệu trong một Process (Với A,B,C,D là các tín hiệu):

process (C,D)

variable Av, Bv, Ev : integer :=0;

begin

Av := 2;

Bv := Av + C;

Av := D + 1;

Ev := Av * 2;

A <= Av;

B <= Bv;

C <= Cv;

end process;

A = 3 A <= 3 Av = 3

B = 3 B <= 3 Bv = 3

C = 1

D = 2

E = 6 E <= 6 Ev = 6

32

Page 33: Kien Thuc Co Ban VHDL

Khi một phát biểu gán tín hiệu được thực thi, giá trị của biểu thức được tính toán

và giá trị này được chuẩn bị để gán cho tín hiệu sau khi delay. Lưu ý rằng biểu

thức được định lượng tại thời điểm phát biểu và không thực thi ngay mà nó sẽ thực

thi sau một thời gian giữ chậm. Có hai kiểu Delay được cung cấp để chuẩn bị cho

việc thực thi tín hiệu:

- Transport Delay.

- Inertial Delay.

a. Transport Delay.

Nó tương tự như sự giữ chậm bên trong của một dòng điện chạy qua dây dẫn. Nếu

thời gian giữ chậm này được xem như tiêu tốn vào thực hiện công việc nào đó và

tiếp sau nó (đúng thời điểm của một công việc trước hoàn thành) cần phải thực

hiện một công việc khác thì thời gian thực hiện các công việc tiếp theo sẽ được

thêm vào cuối của công việc trước đó. Còn nếu khoảng thời gian cần thực hiện

một công việc tiền định (thời gian thực hiện của một công việc tiếp theo nào đó

đứng trước thời điểm thực hiện một công việc trước) thì câu lệnh Transport sẽ

thực hiện chèn vào và thực hiện công việc tiền định này.

Xem ví dụ sau: Giả sử ta có một process và biểu đồ như sau:

Hình 3.4: Biểu đồ thời gian Transport Delay

Ví dụ:

..........

process (.....)

Begin

S <= transport 1 after 1 ns, 3 after 3 ns, 5 after 5 ns;

S <= transport 4 after 4 ns;

end process;

33

Page 34: Kien Thuc Co Ban VHDL

Như ví dụ và biểu đồ trên ta thấy công việc thứ tư cần thực hiện trước công việc

thứ 5, nhưng trong phần chương trình thì phát biểu của công việc thứ 5 lại được

thực hiện trước công việc thứ tư. Hình vẽ dưới đây mô tả phát biểu Transport, sau

3s đèn sẽ được bật sáng và sáng trong khoảng thời gian đúng bằng thời gian bật

công tắc.

Hình 3.5: Mô tả Transport Delay.

b. Inertial Delay

Inertial Delay (giữ chậm do quán tính), là giá trị mặc định của VHDL. Nó được

dùng cho các thiết bị mà không có phản ứng cho đến khi đầu vào được phép trong

một khoảng thời gian nhất định. Thường thì với tín hiệu có khoảng thời gian tác

động không đều và nhỏ hơn thời gian giữ chậm của các cổng thì sẽ bị bỏ qua.

Với ví dụ trên, mô tả hoạt động của đèn với độ giữ chậm do sức ì quán tính của

mạch. Nếu thời gian tác động của công tắc nhỏ hơn độ giữ chậm của mạch thì đầu

ra sẽ không có tác động hay đèn sẽ không được bật sáng. Giả sử ta có câu lệnh đèn

sẽ được bật sáng sau 3 giây, nhưng công tắc chỉ tác động trong thời gian hai giây

thì đèn sẽ không được bật sáng. Xem hình vẽ 3.6 dưới đây:

34

Page 35: Kien Thuc Co Ban VHDL

Hình 3.6: Mô tả Inertial Delay (thời gian bật công tắc là 2s).

Giả sử ta có câu lệnh bật đèn sau 3s. Khi bật công tắc trong thời gian 4s sau đó tắt

công tắc, thì đèn sẽ được sáng sau khi công tắc bật được 3s và sáng trong 4s đúng

bằng thời gian bật công tắc.

Xem hình 3.7 dưới đây:

Hình 3.7: Mô tả Inertial Delay (thời gian bật công tắc là 4s).

c. So sánh Transport Delay và Inertial Delay

35

Page 36: Kien Thuc Co Ban VHDL

Hình 3.8: So sánh Transport Delay và Inertial Delay.

Như trên hình 3.8 ta thấy trong trường hợp Inertial Delay, tín hiệu A có tác động

trong khoảng 10ns, nhưng câu lệnh thực hiện đầu ra S sau 20ns, vì vậy đầu ra S sẽ

không có tác động. Còn trong trường hợp Transport Delay tín hiệu đầu ra sẽ được

sao y tín hiệu đầu vào sau khi bắt đầu sườn lên của tín hiệu vào có tác động (đúng

bằng khoảng 20 ns của câu lệnh).

3.6.3. Phát biểu IF

Một phát biểu if được dùng để chọn lựa những phát biểu tuần tự cho việc thực thi

dựa trên giá trị của biểu thức điều kiện. Biểu thức điều kiện ở đây có thể là một

biểu thức bất kỳ mà giá trị của chúng phải là kiểu luận lý.

Dạng thông thường của phát biểu if là:

if boolean-expression then

sequential-statements

{elsif boolean-expression then

sequential -statement }

{else

sequential-statement}

end if;

Ví dụ 1:

if sum <=100 then --“<=” is less-than-or-equal-to operator.

SUM:=SUM+10;

end if;

Ví dụ 2:

signal IN1, IN2, OU : STD_LOGIC;

process (IN1, IN2)

begin

36

Page 37: Kien Thuc Co Ban VHDL

if IN1 = '0' or IN2 = '0' then

OU <= '0' ;

elsif IN1 = 'X' or IN2 = 'X' then

OU <= '1';

else

OU <= '1' ;

end if;

end process;

Ví dụ 3:

D_FF : process (D, CLK)

begin

if rising_edge (CLK) then Q <= D;

end if;

end process D_FF;

Hình 3.9: Thực thể D_FF.

3.6.4. Phát biểu CASE

Dạng của phát biểu case là:

case expression is

when choices => sequential -statement -- branch 1

when choices => sequential -statement -- branch 2

-- -- Có thể có nhiều nhánh

{when others => sequential-statement} -- last branch

end case;

Phát biểu case lựa chọn một trong những nhánh cho việc thực thi dựa trên giá trị

của biểu thức. Giá trị biểu thức phải thuộc kiểu rời rạc hoặc kiểu mảng một chiều.

Các chọn lựa (Choices) có thể được diễn tả như một giá trị đơn, hoặc một dải giá

37

Page 38: Kien Thuc Co Ban VHDL

trị bằng việc sử dụng dấu " | " hoặc sử dụng mệnh đề khác. Tất cả các giá trị có thể

có của biểu thức phải được thể hiện trong phát biểu case đúng một lần. Các mệnh

đề khác có thể được sử dụng để bao quát tất cả các giá trị, và nếu có, phải là nhánh

cuối cùng trong phát biểu case. Mỗi một chọn lựa phải có cùng kiểu với kiểu của

biểu thức. Một thí dụ cho phát biểu case:

Ví dụ 1:

type WEEK_DAY is (MON, TUE, WED, THU, FRI, SAT, SUN);

type DOLLARS is range 0 to 10;

variable DAY: WEEK_DAY;

variable POCKET_MONEY: DOLLARS;

case DAY is

when TUE => POCKET_MONEY :=6; -- branch1

when MON | WED => POCKET_MONEY :=2; -- branch2

when FRI to SUN => POCKET_MONEY :=7; -- branch3

when others => POCKET_MONEY :=0; -- branch4

end case;

Nhánh 2 được chọn nếu DAY có giá trị là MON hoặc WED. Nhánh 3 bao gồm các

giá trị FRI, SAT và SUN. Trong khi nhánh 4 gồm các giá trị còn lại là THU. Phát

biểu case cũng là phát biểu tuần tự, tuy nhiên nó cũng có thể được phát biểu xếp

lồng nhau.

Ví dụ 2:

ProgrGate: process (Mode, PrGIn1, PrGIn2)

begin

case Mode is

when “000” => PrGOut <= PrGIn1 and PrGIn2;

when “001” => PrGOut <= PrGIn1 or PrGIn2;

when “010” => PrGOut <= PrGIn1 nand PrGIn2;

when “011” => PrGOut <= PrGIn1 nor PrGIn2;

when “100” => PrGOut <= not PrGIn1;

when “101” => PrGOut <= not PrGIn2;

when others => PrGOut <= ‘0’;

end case;

end process ProgrGate;

38

Page 39: Kien Thuc Co Ban VHDL

Hình 3.10: Thực thể Programmable Gate.

3.6.5. Phát biểu NULL

Phát biểu null

Là một phát biểu tuần tự không gây ra bất kỳ hành động nào. Hệ thống sẽ bỏ qua

phát biểu NULL và tiếp tục thực thi với phát biểu kế tiếp. Một thí dụ cho việc sử

dụng phát biểu này là trong phát biểu if hoặc trong phát biểu case.

Ví dụ:

Variable A, B : INTEGER range 0 to 31 ;

Case A is

when 0 to 12 => B:= A;

when others => Null;

End Case;

3.6.6. Phát xác nhận ASSERTION

Phát biểu xác nhận rất hay dùng cho việc kiểm tra thời gian và các điều kiện ngoài

dải.

Ví dụ:

assert (X >3 )

report " Setup violation"

severity warning;

3.6.7. Phát biểu Loop

Một phát biểu lặp được sử dụng để lặp lại một loạt các câu lệnh tuần tự.

Cú pháp của phát biểu lặp là:

[loop-label:] iteration-scheme loop

39

Page 40: Kien Thuc Co Ban VHDL

sequential-statements

end loop [loop-lebel];

Có 3 kiểu sơ đồ lặp. Đầu tiên là sơ đồ lặp có dạng:

for identifier in range

Ví dụ 1: Ví dụ về For ...Loop

FACTORAL:=1;

for NUMBER in 2 to N loop

FACTORAL :=FACTORAL*NUMBER;

end loop;

Trong thí dụ này, thân của vòng lặp thực thi N-1 lần, với định danh lặp là

NUMBER và tăng lên 1 sau mỗi vòng lặp. Đối tượng NUMBER được khai báo ẩn

trong vòng lặp tùy thuộc vào kiểu integer, nó có giá trị từ 2 đến N. Vì vậy khai

báo không rõ ràng cho định danh vòng lặp là điều cần thiết, định danh vòng lặp

cũng không thể được gán cho bất kỳ giá trị nào trong vòng lặp for. Nếu một biến

khác có cùng tên được tạo bên ngoài vòng lặp for, đó là hai loại biến được giải

quyết riêng rẽ và biến sử dụng trong vòng lặp for sẽ chuyển giao cho định danh

vòng lặp. Vùng của vòng lặp FOR cũng có thể là vùng của một kiểu liệt kê.

Ví dụ 2:

type HEXA is (‘0’,’1’,’2’,’3’,’A’,’B’,’C ’); . . . .

for NUM in HEXA’(‘2’) downto HEXA’(‘0’) loop

-- Num sẽ lấy những giá trị trong kiểu HEXA từ 2 cho đến 0.

end loop;

Ví dụ 3: Ví dụ về While .... loop

process

variable Count : integer := 0;

begin

wait until Clk = ‘1’;

while Level = ‘1’ loop

Count := Count +1;

wait until Clk = ‘0’;

end loop;

end process;

40

Page 41: Kien Thuc Co Ban VHDL

3.6.8. Phát biểu NEXT

Phát biểu next cũng là phát biểu liên tục cũng chỉ có thể sử dụng bên trong vòng

lặp. Cú pháp tương tự như phát biểu exit:

next [loop-label][when condition];

Kết quả của phát biểu next sẽ bỏ qua những phát biểu còn lại trong lần lặp hiện tại

của vòng lặp và tiếp tục thực thi với phát biểu đầu tiên trong vòng lặp kế tiếp. Nếu

tồn tại một lần và nếu nhãn vòng lặp không rõ ràng thì sẽ xảy ra hiện tượng lặp

đến vô cùng. Đối lập với phát biểu exit, nó là nguyên nhân của vòng lặp bị giới

hạn.

Ví dụ 1:

for j in 10 downto 5 loop

if SUM < TOTAL_SUM then

SUM:=SUM +2;

elsif SUM = TOTAL_SUM then

next;

else

null;

end if;

K:=K+1;

end loop;

Khi phát biểu next được thực thi, quá trình thực hiện sẽ nhảy đến phần cuối của

vòng lặp (phát biểu cuối cùng K := K+1) sau đó giảm giá trị của định danh vòng

lặp j, và thực hiện lại từ đầu.

Ví dụ 2:

signal DataBus : bit_vector(3 downto 0);

signal Ones : integer;

CountOnes: process (DataBus)

variable NumOfOnes : integer := 0;

begin

for Cntr in 3 downto 0 loop

next when DataBus(Cntr) = ‘0’;

NumOfOnes := NumOfOnes + 1;

end loop;

41

Page 42: Kien Thuc Co Ban VHDL

Ones <= NumOfOnes;

end process CountOnes;

3.6.9. Phát biểu EXIT

Phát biểu exit là một phát biểu tuần tự nó chỉ có thể sử dụng bên trong vòng lặp.

Nó có thể làm cho quá trình thực hiện nhảy đến vòng lặp trong cùng hoặc ra khỏi

vòng đến vị trí của nhãn xác định nào đó khi nó gặp nhãn này trong vòng lặp.

Cú pháp của một phát biểu exit là:

exit [loop-label][when condition]

Nếu nhãn vòng lặp không được chỉ ra thì quá trình thực hiện sẽ lặp đến vòng lặp

trong cùng. Nếu mệnh đề WHEN được sử dụng thì việc tồn tại vòng lặp chỉ xảy ra

nếu điều kiện là đúng. Ngược lại, việc thực hiện sẽ tiếp tục với phát biểu kế tiếp.

Ví dụ:

SUM :=1; J:=0 ;

L3:loop

J:=J+21;

SUM:=SUM*10

if (SUM >100) then

exit L3; -- Thực hiện exit khỏi L3 nếu Sum> 100

enf if;

end loop L3;

3.6.10. Phát biểu WAIT

Như chúng ta đã thấy, một quá trình mô phỏng có thể trì hoãn (hay treo sự thực

hiện của một phát biểu Process hoặc một chương trình con ) cho đến khi gặp một

điều kiện phù hợp. Có 3 hình thức cơ bản của phát biểu wait.

wait on sensitivity-list;

42

Page 43: Kien Thuc Co Ban VHDL

wait until boolean -expression;

wait for time-expression;

Ví dụ 1:

wait on A,B ;

wait until A = B;

wait for 10 ns;

wait on CLOCK for 20 ns ;

wait until SUM >100 for 50 ms;

Sự hiện diện của sensitivity list trong một quá trình trùng với trường hợp một

trong ba trường hợp trên của phát biểu “wait”. Một phát biểu quá trình có wait on

ở cuối của Process tương đương với một phát biểu quá trình có khai báo

sensitivity-list.

Xem hình dưới đây: Hai process này là tương đương nhau.

process

begin

somestatements1;

somestatements2;

somestatements3;

wait on SomeSign;

end process;

-------------------

process (SomeSign)

begin

somestatements1;

somestatements2;

somestatements3;

end process;

Ví dụ 2:

process -- Không sensitivity list

variable TEMP1, TEMP2:BIT;

begin

TEMP1:=A and B;

TEMP2:=C and D;

43

Page 44: Kien Thuc Co Ban VHDL

TEMP1:=TEMP1 or TEMP2;

Z<=not TEMP1;

wait on A, B, C, D; -- Thay thế cho sensitivity-list ở đầu Process .

End process.

Ví dụ 3: Hai Process trong ví dụ dưới đây chỉ ra hai process có phát biểu Wait on.

Process bên trái sẽ làm cho Process treo ngay sau khi Start và chờ cho đến khi có

sự kiện xuất hiện trên tín hiệu SigA. Còn Process bên phải sẽ thực hiện ba câu

lệnh và sau đó rơi vào trạng thái chờ đến khi xuất hiện sự kiện trên tín hiệu SigB.

process

begin

wait on SigA;

somestatements1;

somestatements2;

somestatements3;

end process;

--------------------------

process

begin

somestatements1;

somestatements2;

somestatements3;

wait on SigB;

end process;

3.6.11. Các lời gọi chương trình con

Khi mô tả thiết kế theo kiểu hoạt động hành vi, các chương trình con thường hay

được sử dụng và đưa ra cách thức sử dụng thuận tiện. Có hai loại chương trình con

hay được sử dụng là Hàm và Thủ tục.

- Thủ tục ( Procedure) trả về nhiều giá trị.

- Hàm ( Function ) trả về một giá trị đơn.

Các lời gọi thủ tục sẽ gọi thủ tục mà nó cần được thực hiện trong một quá trình.

Phát biểu trả về ( return ) sẽ là điểm kết thúc một chương trình con, và nó chỉ được

sử dụng trong một hàm hoặc một thủ tục. Đối với hàm thì nó có qui định với phát

44

Page 45: Kien Thuc Co Ban VHDL

biểu trả về trong thân hàm, nhưng với thủ tục thì có thể sử dụng tuỳ ý trong thân

thủ tục. Cú pháp của phát biểu trả về như sau:

return [expression];

Ở đây expression sẽ đưa ra các giá trị trả về của hàm, phát biểu return trong một

hàm cần phải có một biểu thức và giá trị trả về của nó, nhưng đối với phát biểu trả

về trong thủ tục thì không cần phải có mặt của biểu thức. Một hàm có thể có nhiều

hơn một phát biểu trả về, nhưng chỉ có một phát biểu trả về được sử dụng bởi một

lời gọi hàm.

3.7. CÁC PHÁT BIỂU ĐỒNG THỜI

Các phát biểu đồng thời được thực hiện song song trong cùng thời điểm mô

phỏng, chúng không thực hiện theo thứ tự mà chúng được viết ra trong một kiến

trúc. Các phát biểu đồng thời chuyển thông tin thông qua các đường tín hiệu.

Dưới đây là các phát biểu đồng thời được định nghĩa trong VHDL:

- Các phát biểu gán của một quá trình (Process).

- Các phát biểu gán tín hiệu đồng thời .

- Các phát biểu gán tín hiệu điều kiện.

- Các phát biểu gán tín hiệu đợc chọn lựa.

- Các phát biểu Block.

- Các lời gọi thủ tục đồng thời.

- Các phát biểu xác nhận đồng thời.

3.7.1. Phát biểu Process

Phát biểu process là phát biểu bao gồm một tập các phát biểu tuần tự và phát biểu

process lại chính là phát biểu đồng thời. Có nghĩa là tất cả các phát biểu Process

trong một thiết kế được thực hiện một cách đồng thời. Tuy nhiên tại một thời điểm

nhất định được đưa ra chỉ có một phát biểu tuần tự được thực hiện trong mỗi

process. Một Process được kết nối với phần còn lại của thiết kế bởi việc đọc hoặc

viết ra các giá trị từ các tín hiệu và các cổng mà chúng đã được khai báo phía

ngoài Process. Cú pháp của chúng được viết như sau:

[label:] process [(sensitivity_list)]

{process_declaration_part}

begin

45

Page 46: Kien Thuc Co Ban VHDL

{sequential_statements}

end process [label];

Phần khai báo của một process chỉ ra các đối tượng mà vùng hoạt động của nó chỉ

thuộc vùng của một process và chúng có thể là các đối tượng sau đây:

- Khai báo biến .

- Khai báo hằng .

- Khai báo các kiểu.

- Khai báo các kiểu con.

- Khai báo các bí danh Alias.

- Các mệnh đề USE.

Một sensitivity list (tập các sự kiện thay đổi trạng thái cần xử lý trong một quá

trình) có cùng ý nghĩa với một Process có chứa phát biểu wait, mà phát biểu wait

này là phát biểu cuối cùng trong một process và chúng có dạng sau:

Wait on sensitivity list ;

Một process có chức năng giống như một vòng lặp vô hạn mà trong nó có chứa

toàn bộ các phát biểu tuần tự được chỉ ra trong vòng lặp đó. Vì vậy một phát biểu

process cần phải có hoặc một sensitivity list hoặc một phát biểu wait on hoặc cả

hai.

Ví dụ 1:

architecture A2 of example is

signal i1, i2, i3, i4, and_out, or_out : bit;

begin

pr1 : process (i1, i2, i3, i4)

begin

and_out <= i1 and i2 and i3 and i4;

end process pr1;

pr2 : process (i1, i2, i3, i4)

begin

or_out <= i1 or i2 or i3 or i4 ;

end process pr2;

end A2

Ví dụ 2:

name: process (sensitivity list)

46

Page 47: Kien Thuc Co Ban VHDL

declarations

begin

sequential statements;

end process name;

---------------------

MUX2TO1: process (A,B,SEL)

constant High : Bit := ‘1’;

begin

Y <= A;

if (SEL= ‘1’) then Y <= B;

end if;

end process MUX2TO1;

3.7.2. Các phép gán tín hiệu đồng thời

Một dạng khác của việc gán tín hiệu đồng thời đó là các phép gán tín hiệu đồng

thời, các phép gán này được dùng ở bên ngoài của một process nhưng phải nằm

trong một kiến trúc (architecture). Cú pháp của phép gán này như sau:

target_signal <= expression [after time_expression ];

Tương tự như các phép gán tín hiệu tuần tự, mệnh đề after sẽ bị bỏ qua bởi bộ tổng

hợp. Với bất kỳ một tín hiệu nào nằm bên phải của một phép gán đều mang ý

nghĩa tương tự như một phần tử trong sensitivity list .

Một thân architecture có thể chứa số lượng bất kỳ của những phát biểu gán tín

hiệu đồng thời. Vì chúng là những phát biểu đồng thời nên thứ tự của những phát

biểu là không quan trọng. Những phát biểu gán tín hiệu đồng thời được thực thi

bất cứ khi nào có sự kiện xảy ra trong tín hiệu được sử dụng trong biểu thức.

Ví dụ1 :

architecture A1 of example is

signal i1, i2, i3, i4, and_out, or_out : bit;

begin

and_out <= i1 and i2 and i3 and i4;

or_out <= i1 or i2 or i3 or i4;

end A1;

Ví dụ 2:

47

Page 48: Kien Thuc Co Ban VHDL

architecture A2 of example is

signal i1, i2, i3, i4, and_out, or_out : bit;

begin

process (i1, i2, i3, i4)

begin

and_out <= i1 and i2 and i3 and i4;

end process ;

process (i1, i2, i3, i4)

begin

or_out <= i1 or i2 or i3 or i4 ;

end process ;

end A2;

Ví dụ 3:

architecture A3 of example is

signal i1, i2, i3, i4, and_out, or_out : bit;

begin

process

begin

and_out <= i1 and i2 and i3 and i4;

or_out <= i1 or i2 or i3 or i4;

wait on i1, i2, i3, i4;

end A3;

Ba ví dụ trên đây là tương đương nhau.

3.7.3. Các phép gán tín hiệu có điều kiện và các phép gán tín hiệu được

chọn lựa

a. Các phép gán tín hiệu có điều kiện.

Một phép gán tín hiệu có điều kiện chính là một phát biểu đồng thời và có một

đích gán nhất định, tuy nhiên phép gán này có thể có nhiều hơn một biểu thức cho

một đích. Ngoại trừ biểu thức cuối cùng, các biểu thức còn lại phải có một điều

kiện chắc chắn, các điều kiện này được đánh giá theo thứ tự. Nếu một điều kiện

được đánh giá là TRUE thì biểu thức tương ứng được sử dụng, ngược lại các biểu

48

Page 49: Kien Thuc Co Ban VHDL

thức còn lại sẽ được sử dụng. Nhớ rằng chỉ một biểu thức được sử dụng tại một

thời điểm. Cú pháp của câu lệnh này như sau:

target <= {expression [ after time_expression ] when condition else}

expression [ after time_expression ];

Một phát biểu gán tín hiệu có điều kiện có thể được mô tả bởi một phát biểu

process mà process có chứa phát biểu IF. Bạn có thể sử dụng phát biểu gán tín

hiệu có điều kiện ở trong một process .

Ví dụ 1:

architecture A1 of example is

signal a, b, c ,d : integer ;

begin

a <= b when ( d >10 ) else

c when ( d >5 ) else

d;

end A1;

Ví dụ 2:

architecture A2 of example is

signal a, b, c ,d : integer ;

begin

process (b, c, d)

begin

if ( d > 10) then a <= b

elsif ( d >5 ) then a <= c;

else a <= d;

end if;

end process;

end A2;

Ví dụ 3: Sử dụng các phát biểu có điều kiện.

ExProc: process (sensitivityList)

begin

if Cond1

then

….

49

Page 50: Kien Thuc Co Ban VHDL

case Cond2 is

when Val1 => …

when Val2 => …

when others => for I in 1 to 4 loop

….

end loop;

end case;

else

while Cond3 loop

….

end loop

….

end if;

end process ExProc;

b. Các phép gán tín hiệu có chọn lựa.

Phép gán tín hiệu có chọn lựa có thể chỉ một đích gán và cũng chỉ có một biểu

thức with. Giá trị này được kiểm tra giống như phát biểu Case thông thờng. Nó sẽ

quản lý bất cứ sự thay đổi nào xuất hiện tới các tín hiệu được chọn lựa. Cú pháp

của chúng như sau:

with choice_expression select

target <= {expression [after time_expression] when choices}

expression [ after time_expression] when choices;

Bất kỳ phép gán tín hiệu có chọn lựa nào đều có thể được mô tả tương đương bởi

phát biểu process có chứa phát biểu case. Bạn không được sử dụng phát biểu gán

tín có chọn lựa ở trong một process .

Ví dụ 1:

with SEL select

Z <= a when 0 | 1 | 2,

b when 3 to 10,

c when others;

50

Page 51: Kien Thuc Co Ban VHDL

Ví dụ 2:

process ( SEL, a, b, c )

case SEL is

when 0 | 1 | 2| => Z <= a;

when 3 to 10 => Z <= b;

when others => Z <= c;

end case;

end process ;

Hai ví dụ trên đây là hoàn toàn tương đương nhau.

3.7.4. Các phát biểu Block

Các block cho phép người thiết kế nhóm các phần theo trật tự logic của các mẫu

đồng thời, với điều kiện là các phần này không nằm trong lược đồ sử dụng của các

mẫu khác (các mẫu mà chúng được sử dụng để thay thế các thành phần khác trong

một thiết kế). Các block được sử dụng để tổ chức các phát biểu gán đồng thời theo

thứ bậc. Cú pháp của chúng như sau:

label : Block

{block_declarative_part}

begin

{concurrent_statement}

end block [label];

Phần khai báo block chỉ ra các đối tượng thuộc miền cục bộ của block và có thể là

các thành phần sau đây:

- Khai báo tín hiệu.

- Khai báo hằng.

- Khai báo kiểu.

- Khai báo các kiểu con.

- Thân các chương trình con

- Khai báo bí danh ALIAS

- Các mệnh đề use

- Khai báo các thành phần ( Component).

Các đối tượng được khai báo trong một block chỉ được phép hoạt động trong block

đó và các block vòng trong của nó. Khi một block con khai báo một đối tượng có

51

Page 52: Kien Thuc Co Ban VHDL

trùng tên với đối tượng trong block cha thì khai báo của block con sẽ định nghĩa

lại đối tượng trùng tên với block cha.

Ví dụ:

architecture BHV of example is

signal : out 1 : integer;

signal : out 2 : bit;

begin

B1 : block

signal S : bit;

begin

B1-1 : block

signal S : integer;

begin

out 1 <= S ;

end block B1-1;

end block B1;

B2: block

begin

out 2 <= S ;

end block B2;

end BHV;

Trong ví dụ này ta thấy block B1-1 là block con của block B1. Cả B1 và B1-1 đều

khai báo tín hiệu S. Tín hiệu S trong B1-1 sẽ là kiểu integer và truyền cho tín hiệu

out 1 cũng là kiểu integer, mặc dù S được khai báo trong B1 là kiểu Bit. Tín hiệu S

trong B1 được sử dụng trong B2 là kiểu Bit, trùng với kiểu tín hiệu out 2.

3.7.5. Các lời gọi thủ tục đồng thời

Một lời gọi thủ tục đồng thời chính là một lời gọi thủ tục mà nó được thực thi ở

bên ngoài một process, nó đứng độc lập trong một kiến trúc architecture. Lời gọi

thủ tục đồng thời bao gồm:

- Có các tham số IN, OUT, INOUT.

- Có thể có nhiều hơn một giá trị trả về

- Nó được xem như một phát biểu.

52

Page 53: Kien Thuc Co Ban VHDL

- Nó tương đương với một process có chứa một lời gọi thủ tục đơn.

Hai ví dụ dưới đây là tương đương nhau.

Ví dụ 1:

architecture .................

begin

procedure_any (a,b) ;

end..........;

Ví dụ 2:

architecture ................

begin

process

begin

procedure_ any (a,b);

wait on a,b;

end process ;

end .............;

3.7.6. Các chương trình con

Các chương trình con bao gồm các thủ tục và các hàm mà nó có thể được gọi để

thực hiện công việc nào đó lặp lại từ các vị trí gọi khác nhau trong VHDL. Trong

VHDL cung cấp hai kiểu chương trình con khác nhau là:

- Các thủ tục (Procedure).

- Các hàm ( Function ).

a. Hàm và các đặc trưng của hàm.

- Chúng được gọi và thực hiện như một biểu thức.

- Luôn trả về một đối số.

- Tất cả các tham số của hàm đều phải là chế độ mode IN.

- Tất cả các tham số của hàm phải thuộc lớp các tín hiệu hoặc các hằng.

- Bắt buộc phải khai báo kiểu của giá trị trả về.

- Không được chứa các phát biểu Wait.

Cú pháp của hàm được khai báo như sau:

function identifier interface_list return type_mark is

{subprogram_declarative_item}

53

Page 54: Kien Thuc Co Ban VHDL

Begin

{sequential_statement}

end [identifier];

Các định danh identifier chỉ ra tên của một hàm, còn interface_list chỉ ra định dạng

tham số của một hàm.

Mỗi một tham số được định nghĩa theo cú pháp sau:

[class] name_list [mode] type_name [:=expression];

ở đây class của tham số đối tượng phải được chỉ ra là tín hiệu hoặc hằng, còn

mode của đối tượng cần phải là mode in. Nếu không có tham số mode được chỉ ra

thì được hiểu như là mode IN, còn nếu không có tham số class được chỉ ra thì

tham số được hiểu như là một hằng.

Xem ví dụ sau:

process

function c_to_f ( c : real ) return real is

variable f : real;

begin

f := c*9.0/5.0 + 32.0;

return (f);

end c_to_f;

variable temp : real;

begin

temp : = c_to_f (5.0) + 20.0; -- temp = 61

end process;

Tham số chuyển vào hàm được hiểu mặc định là một hằng số, vì không có khai

báo của class.

b. Thủ tục và các đặc trưng của chúng.

- Chúng được gọi như một lời phát biểu.

- Có thể trả về không hoặc một hoặc nhiều đối số.

- Các tham số chuyển giao cho thủ tục có thể là mode in, out, và inout.

- Các tham số chuyển giao cho thủ tục có thể là tín hiệu, hằng, biến.

- Có thể có chứa phát biểu Wait.

Cú pháp khai báo thủ tục như sau:

procedure identifier interface_list is

54

Page 55: Kien Thuc Co Ban VHDL

{subprogram_declarative_item}

begin

{sequential_statement}

end [identifier];

Identifier được sử dụng để chỉ ra tên của procedure và interface_list chỉ ra các

tham số hình thức của procedure. Mỗi tham số được sử dụng theo định nghĩa sau:

[class] name_list [mode] type_name [:=expression];

Class của đối tượng được xem như hằng, biến , hoặc là tín hiệu và mode của đối

tượng có thể là in, out , inout. Nếu không có mode được chỉ ra thì tham số được

hiểu như mode in, nếu không có class được chỉ ra thì các tham số mode in được

hiểu như là các hằng, còn tham số mode out và inout được hiểu như là các biến.

Các tham số có thể là các hằng, các biến, hoặc các tín hiệu và mode của chúng có

thể là in, out, hoặc inout. Nếu lớp của các tham số không xác định rõ ràng thì mặc

nhiên nó là constant, nếu nó là mode in, còn nó là biến nếu mode của tham số đó

là out hoặc inout.

Một ví dụ thân procedure mô tả hành vi hoạt động của các đơn vị logic số học như

sau:

type OP_CODE is ( ADD, SUB, MUL, DIV, LT, LE, EQ);

procedure ARITH_UNIT ( A, B : in INTEGER ;

OP : in OP_CODE ;

Z : out INTEGER;

ZCOMP : out BOOLEAN ) is

begin

case OP is

when ADD => Z := A+B;

when SUB => Z := A-B;

when MUL => Z := A*B;

when DIV => Z := A/B;

when LT => ZCOMP := A<B;

when LE => ZCOMP := A<=B;

when EQ => ZCOMP := A=B;

end case ;

55

Page 56: Kien Thuc Co Ban VHDL

end ARITH_UNIT;

Ta xem một ví dụ khác của thân một procedure, procedure này quay véc tơ đã

được xác định với tên là ARRAY_NAME, bắt đầu từ bit START_BIT tới bit

STOP_BIT, bởi một giá trị ROTATE_BY. Lớp đối tượng của tham số

ARRAY_NAME được xác định một cách tường minh. Biến FILL_VALUE tự

động được khởi tạo về ‘0’ mỗi khi procedure được gọi.

Procedure ROTATE_LEFT

(signal ARRAY_NAME : inout Bit_vector ;

START_BIT, STOP_BIT : in NATUAL;

ROTATE_BY : in POSITIVE ) is

Variable FILL_VALUE : BIT;

begin

assert STOP_BIT > START_BIT

report “STOP_BIT is not greater than START_BIT”

severity NOTE;

for MACVAR3 in 1 to ROTATE_BY loop

FILL_VALUE := ARRAY_NAME (STOP_BIT);

for MACVAR1 in STOP_BIT downto (START_BIT + 1) loop

ARRAY_NAME (MACVAR1) <= ARRAY_NAME (MACVAR1

–1);

end loop;

ARRAY_NAME (START_BIT) <= FILL_VALUE ;

end loop;

end procedure ROTATE_LEFT;

Các procedure được gọi bởi lời gọi procedure. Một lời gọi Procedure có thể là một

phát biểu tuần tự hoặc một phát biểu đồng thời, phát biểu này phụ thuộc vào nơi

xuất hiện lời gọi thủ tục hiện tại. Nếu lời gọi này nằm bên trong một phát biểu

process hoặc một chương trình con khác thì nó được gọi là phát biểu gọi procedure

tuần tự, ngược lại nó được gọi là phát biểu gọi procedure gọi đồng thời.

Cú pháp của phát biểu gọi procedure như sau :

[ label : ] procedure_name ( list_of_actual );

Thực tế các biểu thức, các biến, các tín hiệu hoặc các file, được chuyển vào trong

thủ tục và các tên của đối tượng và các tên này sẽ được dùng để lấy các giá trị tính

56

Page 57: Kien Thuc Co Ban VHDL

toán từ trong thủ tục. Chúng được chỉ ra một cách rõ ràng bởi việc sử dụng sự kết

hợp theo tên và kết hợp theo vị trí .

Ví dụ:

ARITH_UNIT (D1, D2, ADD, SUM, COMP ); -- Sự kết hợp theo vị trí.

ARITH_UNIT ( Z => SUM, B=> D2, A=>D1,

OP=>ADD, ZCOMP => COMP); -- Sự kết hợp theo tên.

Một phát biểu gọi thủ tục tuần tự được thực thi tuần tự cùng với các phát biểu tuần

tự chung quanh nó. Một phát biểu gọi thủ tục đồng thời được thực thi bất cứ lúc

nào khi có một sự kiện xảy ra trên một trong các tham số, mà các tham số này là

một tín hiệu ở chế độ in hoặc inout. Một lời gọi thủ tục đồng thời có nghĩa tương

đương với một process có chứa một lời gọi thủ tục tuần tự và một phát biểu wait.

Phát biểu wait này sẽ làm cho quá trình chờ cho đến khi có một sự kiện xuất hiện

trên các tham số tín hiệu của mode in hoặc inout.

Sau đây là một ví dụ của lời gọi thủ tục đồng thời và phát biểu process tương

đương với nó:

architecture DUMMY_ARCH of DUMMY is

-- Tiếp đến là thân của thủ tục

procedure INT_2_VEC ( signal D : out BIT_VECTOR ;

START_BIT, STOP_BIT : in NATUAL ;

signal VALUE : in INTEGER ) is

begin

-- Mô tả hoạt động hành vi của thủ tục

end INT_2_VEC;

begin

-- Đây là ví dụ của một lời gọi thủ tục đồng thời.

INT_2_VEC (D_ARRAY, START, STOP, SIGNAL_VALUE);

end DUMMY_ARCH;

Phát biểu process tương đương với lời gọi một thủ tục đồng thời như sau:

process

begin

INT_2_VEC (D_ARRAY,START,STOP,SIGNAL_VALUE);

-- Phần thể hiện của các lời gọi thủ tục tuần tự

wait on SIGNAL_VALUE;

57

Page 58: Kien Thuc Co Ban VHDL

-- Chờ sự kiện trên SIGNAL_VALUE và xem chúng nh một tín hiệu

-- vào.

end process;

Một procedure có thể sử dụng hoặc là một phát biểu đồng thời hoặc là phát biểu

tuần tự. Các lời gọi đồng thời thường xuyên được dùng để mô tả chính là các

process.

Ví dụ của thủ tục dùng có khai báo postpone (trì hoãn).

postponend procedure INT_2_VEC ( signal D:out BIT_VECTOR ;

START_BIT,STOP_BIT : in NATUAL;

signal VALUE :in INTEGER) is

begin

-- Phần khai báo hoạt động của thủ tục

end INT_2_VEC;

Ngữ nghĩa của một lời gọi thủ tục đồng thời dùng postponed là tương đương với

ngữ nghĩa của phát biểu process tương ứng với nó và được gọi là phát biểu process

bị trì hoãn.

Một thân process có thể có phát biểu wait, trong khi một function thì không được

phép có. Các function được sử dụng để tính toán các giá trị một cách tức thì. Vì

vậy một function không cần có phát biểu wait trong đó. Một function không thể

gọi một procedure có phát biểu wait trong thủ tục đó.

Một process mà có chứa lời gọi một thủ tục mà trong thủ tục này có chứa phát

biểu wait, thì process này không được khai báo sensitivity list. Hơn nữa từ thực tế

chúng ta thấy một process không thể nhận biết các tín hiệu thuộc sensitivity list vì

nếu có process này sẽ rơi vào trạng thái chờ ngay lập tức.

Với một thủ tục có chứa phát biểu wait thì bất cứ biến hay hằng nào được khai báo

trong thủ tục đó sẽ giữ nguyên giá trị của chúng trong suốt thời gian thực hiện phát

biểu wait và tồn tại chỉ khi thủ tục được kết thúc.

3.8. CÁC ĐÓNG GÓI

Bạn có thể đóng gói để cất các chương trình con, các kiểu dữ liệu, các hằng...

thường dùng để sử dụng chúng trong các thiết kế khác. Một package bao gồm hai

phần chính: Phần khai báo và phần thân package, phần khai báo chỉ ra giao tiếp

cho package.

58

Page 59: Kien Thuc Co Ban VHDL

Cú pháp của khai báo package như sau:

package package _name is

{package _declarative_item}

end [package _name];

Phần package _declarative_item có thể là bất kỳ kiểu nào sau đây:

- Khai báo kiểu.

- Khai báo các kiểu con.

- Khai báo tín hiệu.

- Khai báo các hằng.

- Khai báo bí danh ALIAS.

- Khai báo các thành phần.

- Khai báo các chương trình con.

- Các mệnh đề USE.

Chú ý ! Khai báo tín hiệu trong package có một số vấn đề cần luu ý trong khi tổng

hợp, bởi vì một tín hiệu không thể được chia sẻ bởi hai Entity. Vì vậy nếu muốn

dùng chung khai báo tín hiệu bạn phải khai báo tín hiệu này là tín hiệu toàn cục.

Phần thân của package chỉ ra hoạt động thực tế của một package. Phần thân của

package phải luôn có tên trùng với phần khai báo.

Cú pháp của khai báo này như sau:

package body package _name is

{package _body_declarative-item}

end [package _name] ;

Phần package _body_declarative-item có thể bao gồm:

- Khai báo kiểu.

- Khai báo các kiểu con.

- Khai báo các hằng

- Mệnh đề use.

- Thân các chương trình con.

Ví dụ:

library IEEE;

use IEEE.NUMERIC_BIT.all;

package PKG is

subtype MONTH_TYPE is integer range 0 to 12;

59

Page 60: Kien Thuc Co Ban VHDL

subtype DAY_TYPE is integer range 0 to 31;

subtype BCD4_TYPE is unsigned ( 3 downto 0);

subtype BCD5_TYPE is unsigned ( 4 downto 0) ;

constant BCD5_1: BCD5_TYPE : = b"00001" ;

constant BCD5_7: BCD5_TYPE : = b"00111" ;

function BCD_INC (L : in BCD4_TYPE) return BCD5_TYPE;

end PKG;

package body PKG is

function BCD_INC (L :in BCD4_TYPE) return BCD5_TYPE is

variable V,V1, V2 : BCD5_TYPE;

begin

V1 : = L + BCD5_1;

V2 : = L + BCD5_7;

case V2(4) is

when ' 0 ' => V : = V1;

when ' 1 ' => V : = V2;

end case;

return (V);

end BCD_INC;

end PKG;

3.9. MÔ HÌNH CẤU TRÚC

Thông thường một hệ thống số được mô tả theo tập hợp có thứ bậc của các thành

phần. Mỗi thành phần bao gồm một tập các cổng để có thể giao tiếp được với các

thành phần khác. Khi mô tả một thiết kế trong VHDL và một thiết kế có thứ bậc

chính là một thiết kế đưa ra các khai báo của các thành phần và các phát biểu thể

hiện thành phần đó.

Một đơn vị cơ sở để diễn tả hành vi hoạt động chính là các phát biểu process, còn

đơn vị cơ sở để diễn tả theo kiểu cấu trúc chính là các phát biểu thể hiện của các

đơn vị thành phần. Cả hai loại này đều có thể có mặt trong một thân của một kiến

trúc (architecture).

60

Page 61: Kien Thuc Co Ban VHDL

3.9.1. Các khai báo thành phần

Một thân kiến trúc có thể sử dụng các Entity khác (không trong cùng khai báo của

architecture ), các Entity này được mô tả tách biệt và được đặt trong thư viện thiết

kế. Để sử dụng chúng, người ta dùng các khai báo thành phần và các phát biểu thể

hiện của chúng .Trong mô tả thiết kế, mỗi phát biểu khai báo thành phần phải

tương ứng với một Entity. Các phát biểu khai báo thành phần phải giống với các

phát biểu được chỉ ra trong Entity (các phát biểu giao tiếp vào ra của thành phần

đó). Cú pháp khai báo của chúng như sau:

component component _name

[ port ( local_port_declaration ) ]

end component ;

Trong đó component _name mô tả tên của Entity và port_declaration là khai báo

các cổng của component và phải trùng với phần khai báo đã chỉ ra của component

nằm trong phần khai báo của Entity.

3.9.2. Các thể hiện của component

Một component được định nghĩa trong một architecture có thể được thể hiện thông

qua việc sử dụng các phát biểu thể hiện của chúng. Khi thể hiện chỉ được phép thể

hiện phần giao tiếp của component (bao gồm tên, kiểu, hướng của các cổng vào ra

của chúng), các tín hiệu bên trong chúng không được thể hiện.

Cú pháp thể hiện component như sau:

instantiation_label : component _name

port map (

[ local_port_name =>] expression

{ [local_port_name =>] expression}

);

Một phát biểu thể hiện component cần phải khai báo phần nhãn của thể hiện trước

instantiation_label. Hình vẽ 3.11 và 3.12 dưới đây mô tả phần giao diện và phần

thực thi bên trong của một bộ cộng full_Adder.

61

Page 62: Kien Thuc Co Ban VHDL

Hình 3.11: Phần giao diện component của bộ cộng Full_adder

Hình 3.12: Các thành phần bên trong bộ Full_adder.

Như trên hình vẽ chúng ta thấy phần thực thi có ba loại cổng khác nhau và chúng

được mang tên như sau: OR2_gate, AND2_gate, XOR_gate, chúng được dùng để

xây dựng nên bộ cộng. Để mô tả và thể hiện chúng trong thiết kế, ta có thể viết

chương trình để thực thi từng thành phần của chúng như sau:

library IEEE;

use IEEE.STD_LOGIC_1164.all;

Entity AND2_gate is

port ( I0, I1 : in STD_LOGIC ;

O : out STD_LOGIC );

End AND2_gate;

Architecture BHV of AND2_gate is

Begin

O <= I0 and I1;

End BHV;

-----------

library IEEE;

use IEEE.STD_LOGIC_1164.all;

Entity XOR_gate is

port ( I0, I1 : in STD_LOGIC ;

62

Page 63: Kien Thuc Co Ban VHDL

O : out STD_LOGIC );

End XOR_gate;

Architecture BHV of XOR_gate is

Begin

O <= I0 xor I1;

End BHV;

-------------

library IEEE;

use IEEE.STD_LOGIC_1164.all;

Entity OR2_gate is

port ( I0, I1 : in STD_LOGIC ;

O : out STD_LOGIC );

End OR2_gate;

Architecture BHV of OR2_gate is

Begin

O <= I0 xor I1;

End BHV;

Để thể hiện các component này trong một thiết kế, ta khai báo chúng như sau:

library IEEE;

use IEEE.STD_LOGIC_1164.all;

Entity FULL_ADDER is

port (A, B, Cin : in STD_LOGIC;

Sum, Cout : out STD_LOGIC);

End FULL_ADDER;

Architecture IMP of FULL_ADDER is

component XOR_gate

port ( I0, I1 : in STD_LOGIC; O : out STD_LOGIC );

end component ;

component AND2_gate

port ( I0, I1 : in STD_LOGIC; O : out STD_LOGIC );

end component;

component OR2_gate

port ( I0, I1 : in STD_LOGIC; O : out STD_LOGIC );

63

Page 64: Kien Thuc Co Ban VHDL

end component;

signal N1, N2, N3: STD_LOGIC;

begin

U1 : XOR_gate port map (I0 => A, I1=> B, O=>N1);

U2 :AND2_gate port map ( A, B, N2);

U3 :AND2_gate port map ( Cin, N1, N3);

U4 :XOR_gate port map ( Cin, N1, Sum);

U5 :OR2_gate port map ( N3, N2, Cout);

end IMP;

3.9.3. Các phát biểu Generate

Phát biểu generate là một phát biểu đồng thời và nó được định nghĩa trong phần

architecture. Nó được dùng để mô tả các cấu trúc giống nhau, hay tái tạo lại các

cấu trúc khác giống như bản gốc. Cú pháp của chúng như sau:

instantiation _label : generation_scheme generate

{concurrent_statement}

end generate [instantiation _label];

Có hai loại lược đồ generation : Lược đồ for và lược đồ if. Lược đồ for được dùng

để diễn tả cấu trúc thông thường, nó được dùng để khai báo một tham số generate

và một dải rời rạc của lược đồ for (chỉ ra tham số vòng lặp và dải rời rạc trong các

phát biểu lặp tuần tự). Các giá trị tham số của generate có thể được đọc nhưng

không được gán hay chuyển ra ngoài phát biểu generate.

a. Sử dụng lược đồ for:

Ví dụ: Giả sử ta có bộ cộng 4 bit mà trong đó bao gồm bốn bộ cộng Full_adder

như đã được mô tả ở trên. Xem hình 3.13 dưới đây:

64

Page 65: Kien Thuc Co Ban VHDL

Hình 3.13: Bộ cộng 4 bit.

Để mô tả bộ cộng 4 bit này và sử dụng phát biểu generate, sử dụng mô tả bộ cộng

Full_Adder như trên ta đã mô tả. Ta có thể viết chúng như sau:

architecture IMP of FULL_ADDER4 is

signal X, Y, Z : STD_LOGIC_VECTOR ( 3 downto 0 ) ;

signal Cout : STD_LOGIC ;

signal TMP : STD_LOGIC_VECTOR ( 4 downto 0 ) ;

component FULL_ADDER

port ( A, B, Cin : in STD_LOGIC ;

Sum, Cout : out STD_LOGIC );

end component ;

begin

TMP (0) <= ' 0 ';

G : for I in 0 to 3 generate

FA: FULL_ADDER port map ( X (I), Y(I), TMP (I), Z (I),TMP

(

I+1 )); end generate ;

Cout <= TMP (4);

end IMP;

b, Sử dụng lược đồ if

65

Page 66: Kien Thuc Co Ban VHDL

Hình 3.14: Sơ đồ bộ cộng bốn bit sử dụng một bộ cộng

Half_ADDER và ba bộ cộng Full_ADDER.

Một số cấu trúc có dạng không theo qui luật chuẩn nào, với trường hợp này ta có

thể sử dụng lược đồ if. Giả sử ta mô tả bộ cộng bốn bit như trên hình 3.14 và sử

dụng lược đồ IF generate để mô tả bộ cộng này. Chương trình được viết như sau:

architecture IMP of FULL_ADDER4 is

signal X, Y, Z : STD_LOGIC_VECTOR ( 3 downto 0 ) ;

signal Cout : STD_LOGIC ;

signal TMP : STD_LOGIC_VECTOR ( 4 downto 1) ;

component FULL_ADDER

port ( A, B, Cin : in STD_LOGIC ;

Sum, Cout : out STD_LOGIC );

end component ;

component HALF_ADDER

port ( A, B : in STD_LOGIC ;

Sum, Cout : out STD_LOGIC );

end component ;

begin

G0 : for I in 0 to 3 generate

G1: if I = 0 generate

HA: HALF_ADDER port map ( X (I), Y(I), Z (I), TMP ( I+1 ));

end generate ;

G2: if I >= 1 and I <= 3 generate

66

Page 67: Kien Thuc Co Ban VHDL

FA: FULL_ADDER port map ( X (I), Y(I), TMP (I), Z (I),TMP

( I+1 ));

end generate ;

end generate ;

Cout <= TMP ( 4 );

end IMP;

3.9.4. Các thông số của việc định cấu hình

Trong một Entity có thể có một vài cấu trúc, vì vậy các chi tiết của việc định cấu

hình cho phép người thiết kế chọn các Entity và kiến trúc của nó.

Cú pháp khai báo của chúng như sau:

for instantiation _list : component _name

use Entity library_name. Entity _name [( architecture _name)] ;

Nếu chỉ có một kiến trúc architecture thì tên architecture có thể bỏ qua. Xem thêm

một ví dụ dưới đây:

library IEEE;

use IEEE.STD_LOGIC_1164.all;

Entity FULL_ADDER is

port ( A, B, Cin : in STD_LOGIC;

Sum, Cout : out STD_LOGIC);

End FULL_ADDER;

Architecture IMP of FULL_ADDER is

component XOR_gate

port ( I0, I1 : in STD_LOGIC; O : out STD_LOGIC );

end component ;

component AND2_gate

port ( I0, I1 : in STD_LOGIC; O : out STD_LOGIC );

end component;

component OR2_gate

port ( I0, I1 : in STD_LOGIC; O : out STD_LOGIC );

end component;

signal N1, N2, N3: STD_LOGIC;

for U1 : XOR_gate use entity work.XOR_gate (BHV);

67

Page 68: Kien Thuc Co Ban VHDL

for others : XOR_gate use entity work.XOR_gate (BHV);

for all : AND2_gate use entity work.AND2_gate (BHV);

for U5 : OR2_gate use entity work.OR2_gate (BHV);

begin

U1 : XOR_gate port map (I0 => A, I1=> B, O=>N1);

U2 :AND2_gate port map ( A, B, N2);

U3 :AND2_gate port map ( Cin, N1, N3);

U4 :XOR_gate port map ( Cin, N1, Sum);

U5 :OR2_gate port map ( N3, N2, Cout);

end IMP;

68