You are on page 1of 29

NỘI DUNG

Tìm hiểu và ứng dụng VHDL cho việc thiết kế mạch số

Tâm Trần
(dành riêng cho sinh viên ngành điện-tự động)

SỔ TAY VHDL CƠ BẢN


(Chỉ dành cho sinh viên)
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

Lời nói đầu


Cuốn sổ tay VHDL cơ bản nhằm mục đích giúp người đọc trong thời gian ngắn nhất có thể nắm được các khái
niệm cơ bản và tự thiết kế và mô phỏng được tất cả mô hình mạch số bằng các phương pháp dễ nhất thông
qua các ví dụ cụ thể từ đơn giản như các cổng logic cho tới mạch tổ hợp và tuần tự.

Lưu ý do đây chỉ là một cuốn sổ tay tham khảo nên không thể bao gồm được tất cả các kỹ thuật thiết kế dùng
VHDL. Người đọc cần tham khảo thêm các tài liệu cần thiết trên mạng cho các đoạn mã trong các ví dụ khi cần
hiểu thêm.

Trân trọng,

Tâm

email: kimtam.tran@ut.edu.vn

1
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

Ngôn ngữ VHDL


Giới thiệu

VHDL (VHSIC hardware description language) là một ngôn ngữ mô tả phần cứng được phát triển bởi bộ
quốc phòng Mĩ. Cùng với Verilog, đây là ngôn ngữ rất được ưa sử dụng trong việc thiết kế các thiết bị lập trình
được cỡ lớn (FPGA) hoặc các thiết bị lập trình nhúng (ASIC).

Cần lưu ý là VHDL không phải là ngôn ngữ lập trình ứng dụng mà là một ngôn ngữ đặc tả phần cứng. Không
nên xếp chung với các ngôn ngữ lập trình ứng dụng như C/C++, Java, .Net, PHP …

Một số khác biệt cơ bản giữa Verilog và VHDL

VHDL Verilog
- Được sử dụng trong việc dạy và nghiên - Sử dụng nhiều hơn VHDL trong thực tế.
cứu.
- Dạng ngôn ngữ giống với Ada, Basic. - Dạng cú pháp giống C/C++
- Hay dùng để thiết kế FPGA - Hay dùng để thiết kế ASIC
- Hỗ trợ rất mạnh các kiểu dữ liệu - Hỗ trợ không nhiều các kiểu dữ liệu
- Khó viết và hay gặp lỗi ban đầu, nhưng - Dễ viết do giống cú pháp C/C++, nhưng rất dễ
rất khó xảy ra lỗi khi thiết kế và chạy xảy ra các lỗi vặt
được
- Do hai đặc điểm trên nên khó mở rộng, - Do hai đặc điểm trên nên rất dễ mở rộng nên
nhưng đã mở rộng thì chạy rất ổn định được sử dụng nhiều trên thực tế, nhưng rất dễ
gặp lỗi.
- Được ưu tiên sử dụng khi cần thiết kế - Được sử dụng nhiều với các thiết kế đòi hỏi độ
các mạch đòi hỏi độ chính xác cực cao chính xác cao, trung bình.
(vũ khí, các thiết bị động lực học v.v..)

Cấu trúc chương trình VHDL cơ bản


(nên chỉnh sửa, viết code VHDL dùng notepad++)
-----------------------------------------------------
--Khai báo thư viện
--Khai báo thư viện là việc đầu tiên cần làm trong một chương trình VHDL
--Các thư viện được khai báo có thể là các thư viện chuẩn hoặc các thư viên
--do người dùng định nghĩa
-----------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.my_package.all;
-----------------------------------------------------
--Khai báo entity, các port vào/ra, các hằng
--trong một chương trình VHDL có thể tồn tại nhiều Entity
--khác với khối Entity chính. Các Entity không thể trùng tên, do
--các biến trong từng khối Entity là các biến nội tại.
--Nên tên gọi các biến trong các Entity khác nhau có thể trùng nhau
-----------------------------------------------------
ENTITY entity_name IS
PORT (
port_name: port_mode signal_type;
port_name: port_mode signal_type;
...);
END [ENTITY] [entity_name];

2
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông
-----------------------------------------------------
--Khai báo hoạt động của entity, mối liên hệ vào ra
-----------------------------------------------------
ARCHITECTURE architecture_name OF entity_name IS
--Bên trong khối Architecture có thể khai báo thêm các biến nội tại
--như các tín hiệu (signal), hoặc khai báo các biến, các thành tố (component)
[architecture_declarative_part]
BEGIN
architecture_statements_part
END [ARCHITECTURE] [architecture_name];
----------------------------------------------------------

3
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

1. Thiết kế mạch số tổ hợp sử dụng ngôn ngữ VHDL


1.1 Thiết kế mạch số theo cách luồng dữ liệu (data workflow approach)
Đây là phương pháp đơn giản để viết mã VHDL cho một mạch tổ hợp

Ví dụ về thiết kế mạch tổ hợp sử dụng phương pháp luồng dữ liệu


Thiết kế mạch số sau sử dụng cả hai phương pháp luồng dữ liệu và phương pháp cấu trúc

Phương pháp luồng dữ liệu

Dựa theo mô hình ta có hàm ngõ ra F  BC  ABC


--Đoạn chương trình VHDL theo phương pháp data work flow
---------------------------------------------------------------------------
-----------------------------------
--Khai báo thư viện và thư viện con
LIBRARY ieee ;
USE ieee.std_logic_1164.all ;
---------------------------------------------------------------------------
-----------------------------------
-- Khai báo entity
-- trong trường hợp này có 3 ngõ vào A,B,C và một ngõ ra F. Khối entity đặt
tên là fnc_1
ENTITY fnc_1 IS
PORT (A, B, C: IN STD_LOGIC;
F: OUT STD_LOGIC ) ;
END fnc_1;
---------------------------------------------------------------------------
-----------------------------------
-- Khai báo architecture
-- tên architecture đặt là LogicFunc
ARCHITECTURE LogicFunc OF fnc_1 IS
BEGIN
f <= (B AND NOT C) OR (A AND B AND C);
END LogicFunc;

1.2 Thiết kế mạch số theo cấu trúc (structural approach)


Thiết kế mạch số theo cấu trúc có thể được so sánh với việc chúng ta lắp ráp một mạch
số bằng cách sử dụng nhiều chip vi mạch hoặc các khối mạch số nhỏ, được gọi chung là
các thành tố (components) lại với nhau để tạo thành mạch chức năng theo yêu cầu. Liên
kết giữa các thành tố này được gọi chung là các tín hiệu.

4
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

Ưu điểm của phương pháp thiết kế theo lối cấu trúc:

 Cấu trúc bên trong của mạch sẽ được hiểu rõ tường minh hơn so với phương pháp
luồng dữ liệu.
 Các thành tố (các chip vi mạch) chỉ cần khai báo một lần trong khối Entity. Các đối
tượng mạch cụ thể sẽ được gọi lại trong khối Architecture (xem ví dụ bên dưới).
 Dễ thay đổi, nâng cấp và quản lý việc thiết kế khi mạch lớn
 Dễ kiểm tra và ít lỗi
Nhược điểm

 Phức tạp, nhất là đối với những mạch nhỏ


 Chương trình dài hơn so với phương pháp luồng dữ liệu

1.2.1 Các thành tố trong VHDL (VHDL Components)


Các thành tố trong VHDL có thể được xem như các khối giao tiếp (interface) được khai
báo ở đầu chương trình. Những khối giao tiếp này sau đó sẽ được sử dụng lại nhiều lần
trong khối chức năng (architecture) bao nhiêu lần tùy ý. Ví dụ như trong một khối mạch
số ta cần thiết kế có nhiều cồng OR, bằng cách khai báo khối giao tiếp OR ở đầu chương
trình, ta có thể cụ thể hóa bao nhiêu cổng OR tùy ý trong khối chức năng. Quá trình cụ
thể hóa này được gọi là ánh xạ cổng, sẽ được trình bày trong các phần sau.

1.2.2 Tín hiệu trong VHDL (VHDL signals)


Tín hiệu trong VHDL có thể hiểu một cách thực tế là các kết nối vật lý liên kết các thành
tố (Component) trong mạch lại với nhau. Tín hiệu trong VHDL có hai đặc điểm cần lưu ý
sau

 Chỉ khả dụng nếu thiết kế mạch theo phương pháp cấu trúc hoặc kết hợp giữa cấu
trúc và luồng dữ liệu. Trong phương pháp luồng dữ liệu đơn thuần thì không có.
 Tín hiệu phải được khai báo trong khối ARCHITECTURE. Điều này khác với
các ngõ vào ra thông thường vốn được khai báo trong khối ENTITY

1.2.3 Ví dụ về thiết kế mạch tổ hợp bằng phương pháp cấu trúc


Ví dụ 1: Viết mã VHDL cho mô hình cho trước
Thiết kế mạch sau sử dụng phương pháp cấu trúc

5
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

Dựa vào sơ đồ hình vẽ ta có thể thấy mạch có thể được chia làm:
- 4 khối giao tiếp: khối 1 là cổng AND 3 ngõ vào, khối 2 là cổng NOT một ngõ vào,
khối 3 là cổng AND hai ngõ vào, và khối 4 là cổng OR hai ngõ vào
- Có 3 tín hiệu cần được định nghĩa, lần lượt là S1, S2, S3, dùng để liên kết các khối
lại với nhau. Tín hiệu S1 liên kết khối 1 và 3, S2 liên kết khối 2 và 3, S3 liên kết
khối 3 và 4 như hình vẽ
- Kết luận, để thiết kế theo mô hình cấu trúc, chương trình VHDL cần phải làm các
việc sau:
o Khai báo tín hiệu vào (A, B, C) ra (F) cho mạch chính trong khối Entity
chính
o Khai báo ngõ vào/ra cho các khối giao tiếp (các thành tố --components)
trong các Entity phụ riêng biệt.
o Định nghĩa cách hoạt động của các thành tố trong các khối Architecture
phụ
o Khai báo các tín hiệu S1, S2, S3 trong khối Architecture chính
o Khai báo các khối giao tiếp G1, G2, G3 trong khối Architecture chính
o Bên trong khối Architecture chính, anh xạ các ngõ vào/ra và các tín hiệu với
các tín hiệu vào/ra của các khối giao tiếp
o Lưu ý:
 Tên của các thành tố, ở đây là các Entity phụ phải khác nhau và phải
khác với tên khối Entity chính
 Các cổng khai báo trong các khối Entity (chính hoặc phụ) là các biến
nội tại (internal), do đó được phép trùng nhau giữa các Entity.
 Các khối Architecture của các entity khác nhau được phép trùng tên
 Các tín hiệu (signal) phải được khai báo trong khối Architecture chính
Khối chương trình viết theo phương pháp cấu trúc (tham khảo hình trên)
-- Khai báo entity cho cổng NOT, ký hiệu là B_INV
-- Cổng NOT gồm 1 ngõ vào I1 và 1 ngõ ra O1
------------------------
entity B_INV is
------------------------
port(
I1 : in bit;

6
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông
O1 : out bit
);
end B_INV;

-- Khai báo architecture cho cổng NOT


------------------------------
architecture FUNC of B_INV is
------------------------------
begin
O1 <= not I1;
end FUNC;

--Khai báo entity cho cổng AND 2 ngõ vào


--Cổng AND 2 ngõ vào gồm 2 ngõ vào I1,I2 và 1 ngõ ra O1
--------------------
entity B_AND2 is
--------------------
port(
I1 : in bit;
I2 : in bit;
O1 : out bit
);
end B_AND2;

--Khai báo architecture cho cổng AND 2 ngõ vào


------------------------------
architecture FUNC of B_AND2 is
------------------------------
begin
O1 <= (I1 and I2 );
end FUNC;

--Khai báo entity cho cổng AND 3 ngõ vào


--Cổng AND 3 ngõ vào gồm 3 ngõ vào I1,I2,I3 và 1 ngõ ra O1
--------------------
entity B_AND3 is
--------------------
port(
I1 : in bit;
I2 : in bit;
I3 : in bit;
O1 : out bit
);
end B_AND3;
--Khai báo architecture cho cổng AND 3 ngõ vào
------------------------------
architecture FUNC of B_AND3 is
------------------------------
begin
O1 <= (I1 and I2 and I3 );
end FUNC;

--Khai báo entity cho cổng OR 2 ngõ vào


--Cổng OR 2 ngõ vào gồm 2 ngõ vào I1,I2 và 1 ngõ ra O1
--------------------
entity B_OR2 is
--------------------
port(
I1 : in bit;

7
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông
I2 : in bit;
O1 : out bit
);
end B_OR2;

--Khai báo architecture cho cổng AND 2 ngõ vào


------------------------------
architecture FUNC of B_OR2 is
------------------------------
begin
O1 <= (I1 or I2 );
end FUNC;

--Khai báo khối Entity chính của chương trình


--Đặt tên khối Entity chính là Global
--Khối Global gồm 3 ngõ vào A, B, C và một ngõ ra F
----------------------------------------------
entity Global is
----------------------------------------------
port (
A, B, C: in bit;
F : out bit;
);

end Global;

-- Khai báo Architecture cho khối Global


-- Đặt tên là Structure
---------------------------------------------
architecture Structure of Global is
---------------------------------------------
-- Khai báo các component được sử dụng trong khối chính.
-- Các Components sẽ lần lượt được khai báo.
-- Các cổng (port) của các component được khai báo trong khối Architecture chính
-- phải trùng với các cổng được khai báo trong các khối Entity phụ bên trên
-- Tên các Component phải trùng với tên các Entity được khai báo tương ứng
-- là B_AND3, B_INV, B_AND2, B_OR2
component B_AND3
port(I1,I2,I3:Bit;O1:out Bit);
end component;

component B_INV
port(I1:Bit;O1:out Bit);
end component;

component B_AND2
port(I1,I2:Bit;O1:out Bit);
end component;

component B_OR2
port(I1,I2:Bit;O1:out Bit);
end component;

--Khai báo các tín hiệu (Signal) trong khối chính


--Đặt tên là S1, S2, S3
signal S1,S2,S3: bit;

--Khối hàm chính

8
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông
--Việc ánh xạ các cổng vào ra của các khối giao tiếp với các tín hiệu và ngõ vào/ra chính được
thực hiện ở đây
begin
--Ánh xạ khối giao tiếp cổng And 3 ngõ vào
--Khối G1 có ba ngõ vào A, B, C và ngõ ra là tín hiệu S1
G1 : B_AND3 port map(I1=>A,I2=>B,I3=>C,O1=>S1);

--Ánh xạ khối giao tiếp cổng Not 1 ngõ vào


--Khối G2 có 1 ngõ vào C và ngõ ra là tín hiệu S2
G2 : B_INV port map(I1=>C,O1=>S2);

--Ánh xạ khối giao tiếp cổng And 2 ngõ vào


--Khối G3 có hai ngõ vào S2, B và ngõ ra là tín hiệu S3
G3 : B_AND2 port map(S2,B,S3);

--Ánh xạ khối giao tiếp cổng Or 2 ngõ vào


--Khối G4 có hai ngõ vào S1, S3 và ngõ ra là ngõ ra F
G4 : B_OR2 port map(S1,S3,F);

end structure;

Kết quả mô phỏng bằng giản đồ xung

Ví dụ 2: Thiết kế và viết mã VHDL cho một mạch chức năng cụ thể


Yêu cầu:
Thiết kế bộ cộng 4 bit bằng ngôn ngữ VHDL sử dụng phương pháp cấu
trúc.
Giải quyết:
Theo cách thông thường, khi thiết kế bộ cộng 4 bít, chúng ta theo các bước tuần tự sau:

B1: xác định ngõ vào ra

 Ngõ vào cho hai số nhị phân 4 bit: A4 A3 A2 A1 , B4 B3 B2 B1. Một ngõ vào cho bit nhớ
Cin1 (kí hiệu Cin1 vì ngõ vào này đại diện cho bit nhớ trước bit có trọng số bé nhất)
 5 ngõ ra gồm các bit tổng S1, S2, S3, S4 và bit nhớ Cout4 (kí hiệu này vì bit này đại diện
cho bit nhớ có được sau khi cộng hai bit có trọng số cao nhất)

B2: Kẻ bảng sự thật (tùy chọn)

B3: Thiết lập hàm ngõ ra dựa vào các ngõ vào

B4: Vẽ sơ đồ khối

B5: Viết chương trình cho sơ đồ khối bên trên

9
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

Ta nhận xét thấy bộ cộng 4 bit có thể được ghép nối từ 4 bộ cộng toàn phần 1 bit, do đó
ngay từ bước 3, không cần phải viết hàm ngõ ra mà chúng ta vẫn có thể thiết lập sơ đồ
khối của mạch cộng 4 bit như sau

Dựa trên sơ đồ trên, việc viết chương trình VHDL gồm:

B1: Tạo một file cho việc thiết kế bộ cộng toàn phần một bit như sau và đặt tên
là FullAdder.vhd (trùng tên entity).

 Khai báo khối cộng toàn phần 2 bit cơ bản, bao gồm khối Entity và Architecture

Mã VHDL cho mạch cộng toàn phần hai số nhị phân 4 bits
--Khai bao thu vien va cac thu vien con dung cho chuong trinh
LIBRARY ieee;
USE ieee.std_logic_1164.all;

--Khai bao Entity cho bo cong toan phan hai bit co ban
--Ngo vao gom hai bit can cong va bit nho
entity FullAdder is
port (A, B, CIN: in bit; SUM, COUT: out bit);
end entity FullAdder;

--Khai bao khoi architecture cho bo cong toan phan hai bit co ban
architecture subLogicOperation of FullAdder is
begin
SUM <= (A xor B) xor CIN;
COUT <= ((A xor B) and CIN) or (A and B);
end architecture subLogicOperation ;

B2: Tạo một file mới cùng thư mục với file FullAdder vừa tạo

 Khai báo khối cộng toàn phần 4 bit, gồm Entity (các port) và Architectire
 Bên trong Architecture
o Khai báo các thành tố (component) trước câu lệnh begin
 Khai báo các biến tín hiệu trung gian, trong trường hợp này là các tín hiệu cho
các bít nhớ ngõ ra cho từng khối cộng 2 bit.
 Khai báo các đối tượng cho các thành tố, ở đây là các bộ cộng toàn phần, và
ánh xạ các cổng vào/ra và tín hiệu của khối mạch chính với các ngõ vào/ra của
các đối tượng.

10
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

Mã VHDL cho mạch cộng toàn phần hai số nhị phân 4 bits, tên file phải trùng với tên của
entity. Trong trường hợp này là FourBitfullAdder.vhd
--Khai bao thu vien va cac thu vien con dung cho chuong trinh
LIBRARY ieee;
USE ieee.std_logic_1164.all;

--Khai bao Entity cho bo cong toan phan 4 bit (co bit nho)
--Gom 9 ngo vao (hai so nhi phan 4 bits va mot bit nho)
--5 ngo ra gom so nhi phan 4 bits tong va 1 bit nho
entity FourBitfullAdder is
port (A1, A2, A3, A4, B1, B2, B3, B4, C0: in bit;
S1, S2, S3, S4, C4 : out bit);
end entity FourBitfullAdder ;

--Khai bao architecture cho bo cong toan phan 4 bit


architecture LogicOperation of FourBitfullAdder is
--Khai bao component (thanh to) cho bo cong toan phan hai bit.
--Ten cua component phai trung voi ten cua Entity da duoc khai bao
component FullAdder is
port (A, B, CIN: in bit; SUM, COUT: out bit);
end component FullAdder;
--Khai bao cac tin hieu (signal) trung gian su dung trong mach
signal C1, C2, C3: bit;
--Khoi chuong trinh chinh cua architecture
begin
--Cu the hoa 4 khoi cong 2 bit co ban thong qua Component va lan luot anh xa cac port
--o day co 4 khoi cong hai bit can duoc tao, FA1, FA2, FA3, FA4
FA1: FullAdder port map (A => A1, B => B1, CIN => C0, SUM => S1, COUT => C1);
FA2: FullAdder port map (A => A2, B => B2, CIN => C1, SUM => S2, COUT => C2);
FA3: FullAdder port map (A => A3, B => B3, CIN => C2, SUM => S3, COUT => C3);
FA4: FullAdder port map (A => A4, B => B4, CIN => C3, SUM => S4, COUT => C4);
end architecture LogicOperation;

1.3 Thiết kế mạch số tổ hợp sử dụng các câu lệnh điều kiện và các tiến
trình
Thiết kế mạch số sử dụng phương pháp cấu trúc có lợi thế là giúp làm rõ cấu trúc bên
trong mạch (các cổng cơ bản, cách liên kết các cổng). Tuy nhiên., tong nhiều trường hợp
thiết kế mạch số, việc hiểu biết chi tiết bên trong mạch cấu tạo cụ thể ra sao không quan
trọng, điều khiến ta quan tâm là các mối liên hệ logic giữa các ngõ vào và các ngõ ra.
Trong những trường hợp như vậy, ta có thể dùng các câu lệnh điều khiển để thiết kế cho
vi mạch.

Thiết kế mạch số sử dụng câu lệnh có điều kiện và các tiến trình
Viết mã code VHDL cho bộ giải mã 416.

11
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

Cách 1: Thiết kế mã VHDL dựa theo hàm logic vào/ra (theo bảng sự thật)và các cổng
logic cơ bản
library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

--Khai bao EItity cho bo giai ma 4-->16, khai bao cac cong roi rac
--Cong cho phep EI tich cuc muc cao
entity 1of16Decoder is
port (A0, A1, A2, A3, EI: in bit;
OUT0, OUT1, OUT2,OUT3, OUT4, OUT5,
OUT6, OUT7, OUT8, OUT9, OUT10,
OUT11, OUT12, OUT13, OUT14, OUT15: out bit);
EId EItity 1of16Decoder;

--Khai bao khoi architecture


architecture LogicOperation of 1of16Decoder is

begin
--Hoat dong cua bo giai ma theo bang su that
OUT0 <= not(not A0 and not A1 and not A2 and not A3 and EI);
OUT1 <= not(A0 and not A1 and not A2 and not A3 and EI);
OUT2 <= not(not A0 and A1 and not A2 and not A3 and EI);
OUT3 <= not(A0 and A1 and not A2 and not A3 and EI);
OUT4 <= not(not A0 and not A1 and A2 and not A3 and EI);
OUT5 <= not(A0 and not A1 and A2 and not A3 and EI);
OUT6 <= not(not A0 and A1 and A2 and not A3 and EI);
OUT7 <= not(A0 and A1 and A2 and not A3 and EI);
OUT8 <= not(not A0 and not A1 and not A2 and A3 and EI);
OUT9 <= not(A0 and not A1 and not A2 and A3 and EI);
OUT10 <= not(not A0 and A1 and not A2 and A3 and EI);
OUT11 <= not(A0 and A1 and not A2 and A3 and EI);
OUT12 <= not(not A0 and not A1 and A2 and A3 and EI);
OUT13 <= not(A0 and not A1 and A2 and A3 and EI);
OUT14 <= not(not A0 and A1 and A2 and A3 and EI);
OUT15 <= not(A0 and A1 and A2 and A3 and EI);

end architecture LogicOperation;

12
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

Cách 2: Thiết kế mã VHDL dựa theo hàm logic vào/ra (theo bảng sự thật) và các mệnh
đề có điều kiện
Với cách này chúng ta sẽ dùng một khái niệm rất hay được sử dụng trong VHDL khi thiết
kế mạch tổ hợp sử dụng các chip vi mạch cho sẵn hoặc trong thiết kế mạch tuần tự. Đó
là tiến trình (process)
Ý tưởng của việc sử dụng process trong thiết kế là do đặc điểm của mạch tổ hợp là ngõ
ra sẽ thay đổi trạng thái khi có sự thay đổi ở ngõ vào VHDL, mặc định các đối tượng ngõ
vào/ra được xử lý song song, điều này sẽ gây khó khăn khi thiết kế các mạch mà giữa
các ngõ vào trên thực tế có các mức ưu tiên khác nhau hoặc trong thiết kế mạch tuần tự
(xem phần tiếp theo).
Cú pháp:
process (A, EN)
begin
-- đoạn mã được thực thi trong một tiến trình được đặt ở đây và sẽ được chạy tuần
tự
end process;

Lưu ý: Khi thiết kế mạch tổ hợp dùng process, thì các ngõ vào (bao gồm cả ngõ điều
khiển phải nằm trong danh sách xem xét của tiến trình đó

Chương trình VHDL cho vi mạch giải mã 416 sử dụng câu lệnh điều kiện và tiến trình
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

----------------------------------------------
entity Decoder_1of16 is
----------------------------------------------
port (
A:Bit_vector( 3 downto 0 );
O:out Bit_vector( 15 downto 0);
EINot: in bit
);
end Decoder_1of16;

architecture Decoder_1of16_archi of Decoder_1of16 is

begin

process (A,EINot)--cả hai ngõ vào A và EINot đều được xem xét

begin
-- gia tri ngo ra mac dinh khi chip chua duoc cho phep
-- O <= "1111111111111111";
-- ngo vao cho phep tich cuc muc cao
if (EINot = '0') then
case A is
when "0000" => O(0) <= '0';
when "0001" => O(1) <= '0';
when "0010" => O(2) <= '0';
when "0011" => O(3) <= '0';
when "0100" => O(4) <= '0';
when "0101" => O(5) <= '0';

13
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông
when "0110" => O(6) <= '0';
when "0111" => O(7) <= '0';
when "1000" => O(8) <= '0';
when "1001" => O(9) <= '0';
when "1010" => O(10) <= '0';
when "1011" => O(11) <= '0';
when "1100" => O(12) <= '0';
when "1101" => O(13) <= '0';
when "1110" => O(14) <= '0';
when "1111" => O(15) <= '0';
-- gia tri mac dinh khi cac dieu kien tren khong thoa man
when others => O <= "1111111111111111";
end case;
end if;
end process;
end architecture Decoder_1of16_archi;

14
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

2. Thiết kế mạch số tuần tự sử dụng ngôn ngữ VHDL


2.1 Giới thiệu
Thiết kế mạch tuần tự dùng VHDL cũng tương tự như trong mạch tổ hợp, tuy nhiên sẽ có
một số điểm khác biệt nằm ở phần xử lý các xung đồng bộ hoặc bất đồng bộ.
Về cơ bản do cấu tạo thực sự của các thành tố cấu tạo nên mạch tuần tự là các mạch tổ
hợp (và xung clock), do đó việc thiết kế mạch tuần tự có thể theo ba cách thiết kế như
mạch tổ hợp, trong đó chủ yếu là phương pháp cấu trúc và phương pháp dùng câu lệnh
điều kiện và các tiến trình. Tuy nhiên, do có sự đồng bộ hoặc bất đồng bộ của các xung
clock trong mạch. Do đó trên thực tế, ta thường dùng kết hợp hai phương pháp trên.

2.2 Mã VHDL cho các bộ chốt và Flip-flop


Thiết kế bộ đếm nối tiếp cho mạch sau

2.2.1 Bộ chốt loại SR tích cực mức thấp. Sử dụng phương pháp cấu trúc
Mã VHDL cho SR tích cực mức thấp
library IEEE;
use IEEE.std_logic_1164.all;

--Khai bao entity cho SRlatch tich cuc muc thap


--Chu y hai ngo vao co ten goi SNot va RNot muc dich la
de the hien ngo vao tich cuc thap
entity SRLatch is
port (SNot, RNot: in std_logic; Q, QNot: inout
std_logic);
end entity SRLatch;

--Khoi Architecture chinh


architecture LogicOperation of SRLatch is
begin
Q <= QNot nand SNot;
QNot <= Q nand RNot;
end architecture LogicOperation;

2.2.2 Bộ chốt loại D tích cực mức cao. Sử dụng phương pháp cấu trúc

library ieee;
use ieee.std_logic_1164.all;
--Khai bao Entity cho D latch, mot cong cho phep
EN va mot cong du lieu D
--Hai ngo vao deu tich cuc muc cao
entity DLatch1 is
port (D, EN: in std_logic; Q, QNot: inout
std_logic);
end entity DLatch1;
--Khai bao architecture cho D-Latch (xem hinh
ben)
architecture LogicOperation of DLatch1 is
begin
Q <= QNot nand (D nand EN);
QNot <= Q nand (not D nand EN);
end architecture LogicOperation;

15
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

2.2.3 FF loại JK kích cạnh xuống, hai ngõ bất đồng bộ Reset và Preset tích cực
mức thấp
Cách 1: Sử dụng mệnh đề if

library ieee;
use ieee.std_logic_1164.all;
--Khai bao Entity
entity JKFF is
--Q va QNot dung loai buffer hoac inout
(vi dung cho ca ngo vao va ra
port (J, K, Clock, Pre, Res: in
std_logic; Q, QNot: buffer
std_logic);
end entity JKFF;

architecture LogicOperation of JKFF is


begin
--Bat dau process
--Trong truong hop nay flipflop se xem xet cac ngo vao tuan tu la Clock, reset va
preset
when_Reset_Preset:process (Clock, Res, Pre)
--Khai bao mot bien tam dung trong process (bien noi tai chi co tac dung trong
process)
--Lu y la trong truong hop nay co the dung truc tiep ngo vao Q hoac QNot
--Thay vi dung bien (variable) ta co the dung signal.
--Tuy nhien cac version VHDl truoc nam 1998 ko ho tro
variable temp: STD_LOGIC:='0';
begin
if Res='0' then temp:='0';--Luu y cach gan gia tri cho bien, khac voi signal???
elsif Pre='0' then temp:='1';
elsif (Clock'EVENT and Clock = '0') then
if (J='0' and K='0') then temp:= temp;
elsif (J='0' and K='1') then temp:='0';
elsif (J='1' and K='0') then temp:='1';
elsif (J='1' and K='1') then temp:= not temp;
end if;
end if;
Q<=temp;
end process when_Reset_Preset;
QNot<=Q;
end architecture LogicOperation;

Cách 2: Sử dụng mệnh đề case … when

library ieee;
use ieee.std_logic_1164.all;
--Khai bao Entity
entity JKFF_NEW is
--Q va QNot dung loai buffer hoac inout (vi dung cho ca ngo vao va ra
port (J, K, Clock, Pre, Res: in std_logic; Q, QNot: inout std_logic);
end entity JKFF_NEW;

architecture LogicOperation of JKFF_NEW is


--Khai bao signal JK
signal JK: STD_LOGIC_VECTOR (1 DOWNTO 0);
begin
JK<=J&K;

16
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông
when_Reset_Preset:process (Clock, Res, Pre)
begin
if Res='0' then Q<='0';--Luu y cach gan gia tri cho signal, khac voi bien???
elsif Pre='0' then Q<='1';
elsif (Clock'EVENT and Clock = '0') then
case JK is
when "00"=>Q<=Q;
when "01"=>Q<='0';
when "10"=>Q<='1';
when "11"=>Q<=not Q;
when others => Q<=Q;
end case;
end if;
end process when_Reset_Preset;
QNot<=Q;
end architecture LogicOperation;

2.2.4 Mã VHDL cho FF loại D kích cạnh lên, hai chân Preset và Clear đồng bộ tích
cực thấp.

library ieee;
use ieee.std_logic_1164.all;
--Khai bao Entity
entity dff is
port (D, Clock, Pre, Clr: in std_logic; Q: inout std_logic);
end entity dff;
--Khai bao architecture
architecture LogicOperation of dff is
begin
--Xu ly tuan tu cac tin hieu dau vao
--Truong hop nay hai chan Preset va Clear dong bo nen chi quan tam toi xung Clock
process (Clock)
begin
if (Clock'EVENT and Clock = '1') then--neu co xung clock canh len thi
--Kiem tra cong clear khong duoc tich cuc
if Clr = '1' then
if Pre = '1' then
if D = '1' then Q <= '1';
else Q <= '0';
end if;
else
Q <= '1';
end if;
else
Q <= '0';
end if;
else Q<=Q;
end if;
end process;
end architecture LogicOperation;

17
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

18
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

2.3 Mã VHDL dành cho bộ đếm


Về thiết kế bộ đếm ta có hai loại là bộ đếm đồng bộ và bất đồng bộ, không có gì khác biệt về phương cách viết
mã VHDL cho hai loại trên một khi đã có thiết kế sơ đồ bộ đếm cụ thể.

Các bước cần thực hiện khi viết mã cho bộ đếm bất kỳ
B1: Thiết kế bộ đếm để ra được mô hình chi tiết của bộ đếm (modulo?FF loại gì?Bao nhiêu cổng?cần thêm
cổng logic nào?

B2: Căn cứ vào mô hình chi tiết có được trong bước 1 ta tiến hành phân loại mạch ra thành các thành phần
riêng biệt như các Flip-flop theo từng loại, các cổng theo từng loại.

B3: Tạo các file mã VHDL cho từng loại như trên

B4: Tổ hợp các loại trên trong một file mã VHDL cho bộ đếm tổng quát

Ví dụ
Viết mã VHDL cho bộ đếm bất đồng bộ có thiết kế như sơ đồ bên dưới

Bước 1: Phân tích mạch

Nhận xét:

- Mạch gồm ba T-FF mắc nối tiếp. Ở đây giả thiết các chân CLR và PR là bất đồng bộ. Do đó có thể thiết
kế riêng T-FF trong một entity riêng biệt và khai báo lại trong khối architecture chính của bộ đếm (sử
dụng Component).
- Tương tự như T-FF, trong sơ đồ có một cổng logic NAND, ta cũng có thế khai báo riêng entity cho cổng
NAND và khai báo đối tượng trong khối architecture.

Bước 2: Tạo riêng biệt trong cùng một thư mục các file mã VHDL cho từng thành phần
-----------------tạo file VHDL cho
TFF---------------------------------------------------------------------
TFF.vhd------------------------------------
library ieee;
use ieee.std_logic_1164.all;
--Khai bao Entity
entity tff is
port (T, Clock, Pre, Clr: in std_logic; Q,QNot: inout std_logic);
end entity tff;

19
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông
--Khai bao architecture
architecture LogicOperation of tff is
begin
process (Clock)
begin
if (Clock'EVENT and Clock = '0') then--neu co xung clock canh xuong thi
--Kiem tra cong clear khong duoc tich cuc
if Clr = '1' then
if Pre = '1' then
if T = '1' then Q <= not Q;
else Q <= Q;
end if;
else
Q <= '1';
end if;
else
Q <= '0';
end if;
else Q<=Q;
end if;
end process;
QNot<=not Q;
end architecture LogicOperation;

-----------------tạo file VHDL cho cổng NAND 3 ngõ


vào---------------------------------------------------
NAND3.vhd------------------------------------

library ieee;
use ieee.std_logic_1164.all;

entity NAND3 is
port (I0, I1, I2: in std_logic;
Out0: out std_logic
);
end entity NAND3;

architecture NAND3_archi of NAND3 is


signal ABC: STD_LOGIC_VECTOR (2 DOWNTO 0);
begin
ABC<=I2&I1&I0;
inputChange:process (I0, I1, I2)
begin
case ABC is
when "111"=>Out0<='0';
when others =>Out0<='1';
end case;
end process inputChange;
end architecture NAND3_archi;

-----------------tạo file VHDL cho bộ đếm


chính---------------------------------------------------
seq_counter.vhd------------------------------------
library ieee;
use ieee.std_logic_1164.all;
--Khai bao entity, chú ý ngõ ra khai báo dưới dạng biến vector???
entity seq_counter is
port ( clk0: in std_logic;

20
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông
preset: in std_logic;
counter : out std_logic_vector(2 downto 0)
);
end seq_counter;

--Khai báo architecture

architecture seq_counter_archi of seq_counter is


--Khai báo các signal cần thiết
signal Q0,Q1,Q2,QNot0,QNot1,QNot2,S0: std_logic;
--Khai báo component. Tên của component phải trùng tên của entity trong
--file khai báo gốc
component NAND3
port (I0, I1, I2: in std_logic;
Out0: out std_logic
);
end component NAND3;
component TFF
port(T, Clock, Pre, Clr: in std_logic;
Q, QNot: inout std_logic);
end component TFF;

begin
begin
--Ánh xạ các cổng vào
INAND3: NAND3 port map (I2=>Q2,I1=>Q1,I0=>Q0,Out0=>S0);
TFF0: TFF port map (T=>'1', Clock=>clk0, Pre=>preset, Clr=>S0, Q=>Q0,
QNot=>QNot0);
TFF1: TFF port map ('1', QNot0, preset, S0, Q1, QNot1);
TFF2: TFF port map ('1', QNot1, preset, '1', Q2, QNot2);
counter <= Q2 & Q1 & Q0;
end architecture seq_counter_archi;

21
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

3. Thiết kế và mô phòng dùng Maxplus II


3.1 Giới thiệu
MaxPlus II là một phần mềm được phát triển bởi Altera nhằm mục đích giúp thiết kế FPGA dùng các ngôn ngữ
HDL (VHDL/Verilog…).

Phiên bản cuối cùng của MaxPlus II được ra đời nằm 2012 với chuẩn VHDL 93 (!). Các phiên bản sau được phát
triển bởi Altera và Intel được gọi là Quartus. Ta có thể tải phần mêm Quartus phiên bản dành cho nghiên cứu,
học tập (lite edition) trên trang web http://dl.altera.com/?edition=lite

3.2 Ví dụ về cách viết chương trình VHDL cơ bản và thực hiện mô phỏng
trên MaxPlus II.
Hãy thiết kế và mô phỏng mạch tổ hợp dùng VHDL trên Maxplus. Hàm tổ hợp như bên dưới

Bước 1. Chuẩn bị code VHDL


- Có thể sử dụng trực tiếp chương trình editor có sẵn trên Maxplus

- Hoặc dùng một chương trình editor hỗ trợ cú pháp VHDL

- Lưu file vhdl ở dạng “<tên của ‘ENTITY’>.vhd”. Trong trường hợp này là func1.vhd

22
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

Bước 2. Biên dịch chương trình VHDL

- Nhấn Start

23
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

- Nếu chương trình không lỗi thì không có thông báo sai code

Bước 3. Xem mạch thiết kế ở dạng khối

- Mở Graphic Editor

- Nhập Symbol

- Mở file *.gdf (có được khi biên dịch chương trình)

24
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

- Sơ đồ khối mạch xuất hiện

Bước 4: Mô phỏng bằng dạng song


- Mở Waveform Editor

- Nhập file *.snf có được khi biên dịch *.vhd

25
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

- Chọn các ngõ vào/ra

- Chọn các dạng song logic (0..1) cho các cổng vào

26
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

- Lưu file với dạng *.scf

- Chạy mô phỏng

27
Trường ĐH GTVT TPHCM Trần Kim Tâm
Khoa Điện-Điện tử viễn thông

28

You might also like