LỜI NÓI ĐẦU .3
MỤC LỤC.5
CHƢƠNG 1 – GIỚI THIỆU CHUNG VỀ THIẾT KẾ HỆ THỐNG SỐ .8
1.1 GIỚI THIỆU CHUNG .8
1.2 QUY TRÌNH PHÁT TRIỂN HỆ THỐNG ĐIỆN TỬ .9
1.2.1 Quy trình phát triển sản phẩm tuần tự.9
1.2.2 Quy trình phát triển sản phẩm song song .10
1.2 MÔ HÌNH KIẾN TRÚC VÀ CÁC MỨC THIẾT KẾ HỆ THỐNG SỐ .12
1.2.1 Kiến trúc của hệ thống số.12
1.2.2 Các Mức thiết kế hệ thống số.13
1.3. TỔNG QUAN VỀ CÁC CÔNG NGHỆ THỰC HIỆN HỆ THỐNG SỐ.14
1.3.1 Phân loại các công nghệ logic số .14
1.3.2 So sánh các loại cấu kiện chuẩn .17
1.4 QUY TRÌNH THIẾT KẾ VI ĐIỆN TỬ.22
1.5. VAI TRÒ CỦA THIẾT KẾ VI ĐIỆN TỬ SỬ DỤNG HDL.23
1.6 LƢU ĐỒ THIẾT KẾ VI ĐIỆN TỬ DÙNG HDL.25
1.6.1. Thiết kế logic.26
1.6.2. Tổng hợp thiết kế (Synthesis) .26
1.6.3. Thiết kế mức vật lý (Physical Design).26
1.6.4. Kiểm tra thiết kế (Verification) .27
1.6.5 Sản xuất và đóng gói.28
1.7 CÁC PHẦN MỀM EDA HỖ TRỢ THIẾT KẾ LOGIC SỐ DÙNG HDL .28
CHƢƠNG 2 – CẤU KIỆN LOGIC KHẢ TRÌNH (PLD). .30
2.1. GIỚI THIỆU CHUNG VỀ CÔNG NGHỆ LOGIC KHẢ TRÌNH (PLD) .30
2.1.1. SPLD .30
2.1.2. CPLD (Complex PLD) .33
2.1.3. FPGA.34
2.2. GIỚI THIỆU PHƢƠNG PHÁP THIẾT LẬP CẤU HÌNH CHO CPLD/FPGA.36
2.2.1 Phƣơng pháp dùng sơ đồ mô tả .36
2.2.2. Phƣơng pháp dùng ngôn ngữ mô tả phần cứng (HDL) .37
2.3. YÊU CẦU CHUNG KHI THIẾT KẾ VỚI CPLD/FPGA .37
2.3.1 Chọn vi mạch CPLD hoặc FPGA phù hợp .37
2.3.2 Chọn giải pháp cấu hình cho CPDL/FPGA.38
2.3.3 Chọn công cụ phần mềm phù hợp.40
2.4. LƢU ĐỒ THIẾT KẾ CHO CPLD/FPGA.41
2.4.1 Lƣu đồ thiết kế cho CPLD.41
2.4.2 Lƣu đồ thiết kế cho FPGA.44
2.5.3. Ví dụ thiết kế đơn giản dùng phần mềm ISE .46Mục lục
6
CHƢƠNG 3 – CĂN BẢN VỀ NGÔN NGỮ MÔ TẢ PHẦN CỨNG VHDL .65
3.1. LỊCH SỬ PHÁT TRIỂN CỦA VHDL .65
3.2 NHỮNG ƢU ĐIỂM CỦA VHDL .66
3.3 CẤU TRÚC NGÔN NGỮ CỦA VHDL.67
3.3.1 Đối tƣợng trong VHDL .68
3.3.2 Kiểu dữ liệu trong VHDL.70
3.3.3 Các phép toán trong VHDL .81
3.3.4 Các đơn vị thiết kế trong VHDL.87
3.3.5 Cấu trúc chung của một chƣơng trình mô tả VHDL.95
3.3.6 Môi trƣờng kiểm tra “testbench”.97
3.3.7 Các cấu trúc lệnh song song .100
3.3.8 Cấu trúc lệnh tuần tự .111
3.3.9 Hàm và thủ tục .120
BÀI TẬP .126
CHƢƠNG 4 – PHƢƠNG PHÁP THIẾT KẾ LOGIC DÙNG VHDL.128
4.0 GIỚI THIỆU CHUNG VỀ THIẾT KẾ LOGIC DÙNG HDL.128
4.1 MÔ HÌNH BIỂU DIỄN HỆ THỐNG SỐ.129
4.1.1. Mô hình hoạt động (Behavioral views).129
4.1.2. Mô hình cấu trúc (Structural views) .130
4.1.3. Mô hình vật lý (Physical views) .130
4.2 CÁC MỨC ĐỘ TRỪU TƢỢNG TRONG MÔ TẢ HỆ THỐNG SỐ .130
4.2.1. Mô tả mức mạch điện (Circuit Level or Transistor Level) .132
4.2.2. Mô tả mức logic (Logic Lever or Gate Level).132
4.2.3 Mô tả mức RTL (Register Transfer Level – Mức truyền đạt thanh ghi) .132
4.2.4. Mô tả mức hệ thống (System Level or Processor Level).132
4.2.5. Ví dụ các mô hình hệ thống số .133
4.3 MÔ TẢ THEO MÔ HÌNH HOẠT ĐỘNG (BEHAVIORAL) .135
4.3.1 Mô tả theo mức hệ thống.135
4.3.2 Mô tả theo mức RTL.136
4.3.3. Viết mô tả Testbench .139
4.3.4 Mã mô tả VHDL không tổng hợp đƣợc.153
4.4. CÁC MÔ HÌNH TÍN HIỆU SỐ.154
4.5. MÔ TẢ THEO MÔ HÌNH CẤU TRÚC.155
4.6. MÔ TẢ MẠCH LOGIC TỔ HỢP .160
4.6.1. Các cấu trúc lệnh VHDL dùng cho mô tả mạch tổ hợp .160
4.6.2. Mô tả các mạch tổ hợp cơ bản.163
4.6.3. Phƣơng pháp thiết kế dùng chung phép toán.182
4.6.4. Phƣơng pháp thiết kế dùng chung chức năng.188
4.7. MÔ TẢ MẠCH LOGIC TUẦN TỰ CƠ BẢN .190
4.7.1. Cấu trúc lệnh VHDL dùng cho mô tả mạch tuần tự .190
4.7.2. Mô tả các phần tử nhớ .191
4.7.3. Bộ đếm (Counter).197
4.7 MÁY TRẠNG THÁI HỮU HẠN – FSM .206Mục lục
7
4.7.1. Giới thiệu chung về máy trạng thái hữu hạn - FSM .206
4.7.2. Đồ hình máy trạng thái - FSMD .208
4.7.3. Lƣu đồ giải thuật máy trạng thái – ASM.210
4.7.4. Mô tả VHDL cho FSM .212
4.8. PHƢƠNG PHÁP THIẾT KẾ TOP-DOWN .220
BÀI TẬP .221
CHƢƠNG 5 – THIẾT KẾ CÁC HỆ THỐNG SỐ ỨNG DỤNG DÙNG VHDL .222
5.1. THIẾT KẾ MẠCH ĐIỀU KHIỂN HIỂN THỊ LED.222
5.1.1 Thiết kế mạch điều khiển màn chỉ thị số LED.222
5.1.2 Thiết kế mạch điều khiển ma trận LED.227
5.1.3. Thiết kế ứng dụng điều hiển thị 8 led đơn sáng theo quy luật .233
5.2 THIẾT KẾ BỘ ĐẾM THUẬT NGHỊCH THEO ĐIỀU KHIỂN.237
5.3. THIẾT KẾ BỘ ĐẾM TẦN TỰ ĐỘNG THAY ĐỔI THANG ĐO .240
5.4. THIẾT KẾ MẠCH GIAO TIẾP ĐIỀU KHIỂN VGA.248
5.5. THIẾT KẾ MẠCH ĐIỀU KHIỂN HIỂN THỊ LCD.255
5.6 THIẾT KẾ MẠCH ĐIÈU KHIỂN MA TRẬN PHÍM.270
5.7. THIẾT KẾ GIAO TIẾP PS2 VỚI BÀN PHÍM .274
5.8. THIẾT KẾ BỘ ĐIỀU KIỂN TRUYỀN THÔNG NỐI TIẾP UART .279
PHỤ LỤC I – QUY ƢỚC VỀ ĐẶT TÊN TRONG VHDL.289
I.1. Quy ƣớc chung về đặt tên trong VHDL.289
I.2. Quy ƣớc đặt tên các đối tƣợng trong VHDL .290
I.3. Quy ƣớc đặt tên các đơn vị thiết kế .291
PHỤ LỤC II – CẤU TRÖC LỆNH CƠ BẢN CỦA VHDL.293
PHỤ LỤC III – GIỚI THIỆU CPLD/FPGA CỦA XILINX.297
III.1. GIỚI THIỆU CHUNG VỀ CPLD/FPGA CỦA XILINX .297
III.1.1. CPLD của Xilinx .297
III.1.2. FPGA của Xilinx .300
III.2. CẤU TRÚC CPLD CỦA XILINX .301
III.2.1 XC9500XL .301
III.2.2. CoolRunner XPLA3.307
III.2.3 CoolRunner II.309
III.3. GIỚI THIỆU CÁC DÒNG FPGA CĂN BẢN .313
III.3.1. Spartan-3.313
III.3.2. Virtex .317
PHỤ LỤC IV – HƢỚNG DẪN PHẦN MỀM ISE CỦA XILINX .323
IV.1. GIỚI THIỆU CHUNG.323
IV.2. HƢỚNG D N CÀI Đ T .323
t process:
architecture COMBINED of DATAPATH is
signal X1, X2 : ...
begin
process (CLK) -- Registers
begin
if (CLK'event and CLK = '1') then
-- Khối mạch tổ hợp được tổng hợp từ biểu thức F,G.
X2 <= F(X1);
X3 <= G(X2);
X1 <= Y0;
end if;
end process;
end COMBINED;
Chương 4– Phương pháp thiết kế logic dùng VHDL
139
+ Mô hình điều khiển
Trong mô hình hoạt động mức RTL, khối điều khiển (Controller) thƣờng đƣợc mô tả
theo mô hình máy trạng thái hữu hạn. Có hai dạng mô hình biểu diễn máy trạng thái hữu hạn
là:
+ Đồ hình trạng thái (State Diagram).
+ Lƣu đồ máy trạng thái theo giải thuật - ASM (Algorithmic State Machine).
Nội dung về máy trạng thái sẽ đƣợc trình bày chi tiết trong các phần sau.
4.3.3. Viết mô tả Testbench
Nhƣ đã trình bày trong chƣơng 3, Testbech nhƣ một môi trƣờng kiểm tra ảo, cho phép
tạo các nguồn tín hiệu vào kích thích cho khối cần kiểm tra DUT, bên cạnh đó còn có các mô
tả cho việc đọc dữ liệu ra của khối DUT, so sánh với tín hiệu đầu ra mong muốn để tạo để tạo
ra các thông báo trên màn hình cũng nhƣ đọc hay ghi vào các file số liệu trong quá trình chạy
mô phỏng. Các mô tả này chủ yếu đƣợc viết theo mô hình hoạt động (behavioral) và có thể
chỉ dùng cho mục đích mô phỏng. Tổng quát có 2 mô hình cho chƣơng trình Testbech nhƣ
sau:
Hình 4.8 - Sơ đồ tổng quát chƣơng trình thử Testbench đơn giản
Hình 4.9 - Sơ đồ tổng chƣơng trình thử Testbench đầy đủ
DUT
(Device Under Test)
Tạo
nguồn tín
hiệu vào
kích thích
Tiến trình so
sánh tín hiệu ra
thực với tín
hiệu ra mong
muốn
Generics – Tạo tham số
Testbench Entity
Thiết kế đúng hay sai?
DUT Tạo
nguồn tín
hiệu vào
kích thích
Quan sát
tín hiệu ra
theo dạng
sóng
Generics – Tạo tham số
Testbench Entity
Trong đó: DUT: (device under test) mô hình VHDL cần kiểm tra
Chương 4– Phương pháp thiết kế logic dùng VHDL
140
+ Chương trình thử Testbench đơn giản: Chỉ viết mô tả để tạo các nguồn tín hiệu vào
kích thích cho khối cần kiểm tra DUT, còn tín hiệu ra đƣợc thu thập tự động bởi phần mềm
mô phỏng và đƣa kết quả ra dƣới dạng giản đồ thời gian. Phân tích giản đồ thời gian để xác
định hoạt động của khối DUT. Mô hình Testbench đơn giản này nhƣ Hình 4.8.
+ Chương trình thử Testbench đầy đủ: Ngoài mô tả để tạo các nguồn tín hiệu vào kích
thích cho khối cần kiểm tra DUT, trong chƣơng trình Testbench còn thực hiện các tiến trình
đọc kết quả đầu ra của DUT, thực hiện đánh giá kết quả đó hay so sánh với tín hiệu ra mong
muốn để đánh giá xem thiết kế có đúng hay không, kết quả mô phỏng còn có thể đƣợc ghi và
đọc ra file, cũng nhƣ tạo các thông báo trên màn hình dùng các hàm của gói TextIO. Mô hình
Testbench đầy đủ này nhƣ Hình 4.9.
a. Viết mô tả dạng tín hiệu kích thích
Để viết mô tả dạng tín hiệu thƣờng dùng mô hình thời gian của VHDL sử dụng các lệnh
tuần tự hoặc các lệnh song song.
+ Một số mô hình thời gian dùng lệnh gán song song
Có thể dùng các cấu trúc lệnh gán song song có mệnh đề after ;
Ví dụ lệnh gán liên tiếp:
Tín_hiệu, after Biểu_thức_thời_gian,...
after Biểu_thức_thời_gian;
-- sau bao giờ cũng lớn hơn các biểu thức thời gian trước
đó, đó là khoảng thời gian thiết lập so với gốc thời gian
khởi tạo ban đầu.
+ Một số mô hình thời gian dùng lệnh tuần tự
+ Wait on
Ví dụ: Wait on clk, Reset
+ Wait until
Ví dụ: Wait until clk=‟1‟
+ Wait for
Ví dụ: Wait for 10 ns
+ Wait on until
Ví dụ: Wait on clk, Reset
Ví dụ: Wait on Reset until clk=‟1‟
+ Wait until for
+ Trường hợp 1: Viết mô tả để tạo ra dạng tín hiệu đơn a nhƣ hình vẽ dƣới đây:
Chương 4– Phương pháp thiết kế logic dùng VHDL
141
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity TestbechCodes is
end TestbechCodes;
architecture Behavioral of TestbechCodes is
signal a:std_logic;
-- Dùng lệnh gán song song
begin
a<= '1', '0' after 100 ns, '1' after 250 ns;
-- Giá trị khởi tạo của a là '1', sau đó đạt các giá trị khác nhau sau
-- khoảng thời gian xác định so với gốc thời gian bắt đầu khởi tạo tín hiệu
end Behavioral;
-- Dùng lệnh tuần tự
begin
process
begin
a <='1'; wait for 100 ns;
a <='0'; wait for 150 ns;
a <='1';
wait; -- Dừng lại
end process;
end Behavioral;
+ Trường hợp 2: Viết mô tả tạo ra sự thay đổi cho tín hiệu kiểu Vector
-- Khai báo tín hiệu
Signal InputxD: std_logic_vector(1 downto 0);
-- Dùng lệnh gán song song
InputxD<="00", "01" after 100 ns, "10" after 200 ns, "11" after 300 ns;
-- Dùng lệnh tuần tự
process
begin
InputxD<="00"; wait for 100 ns;
InputxD<="01"; wait for 100 ns;
InputxD<="10"; wait for 100 ns;
InputxD<="11";
Chương 4– Phương pháp thiết kế logic dùng VHDL
142
wait;
end process;
+ Trường hợp 3: Viết mô tả tạo ra sự thay đổi cho các tín hiệu Rst, a, InputxD[1:0] có dạng
nhƣ sau:
-- Khai báo tín hiệu
signal A, Rst:std_logic;
signal InputxD: std_logic_vector(1 downto 0);
-- Dùng lệnh gán song song
Rst<='1', '0' after 150 ns;
A<='1','0' after 100ns,'1' after 250ns,'0' after 350ns,'1' after 450ns;
InputxD<="00", "01" after 100 ns, "10" after 200 ns, "11" after 300 ns;
-- Dùng lệnh gán song song và tuần tự
Rst<='1', '0' after 150 ns;
AGen:process
begin
A<='1'; wait for 100 ns;
A<='0'; wait for 150 ns;
A<='1';
wait;
end process;
InputxDGen:process
begin
InputxD<="00"; wait for 100 ns;
InputxD<="01"; wait for 100 ns;
InputxD<="10"; wait for 100 ns;
InputxD<="11";
wait;
end process;
+ Trường hợp 4: Mô tả các dạng tín hiệu clock Clk1, Clk2 có chu kỳ 100 ns nhƣ hình vẽ sau:
Chương 4– Phương pháp thiết kế logic dùng VHDL
143
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ClkGen is
end ClkGen;
architecture Behavioral of ClkGen is
constant Tclk: Time:=100 ns;
constant T2: Time:=30 ns;
signal Clk1, Clk2: std_logic:='1'; -- Giá trị khởi tạo phải xác định
begin
Clk1<= not Clk1 after Tclk/2;
Clk2Gen:process
begin
Clk2<='1'; wait for T2;
Clk2<='0'; wait for (Tclk-T2);
end process;
end Behavioral;
+ Trường hợp 5: Tạo ra tất cả các giá trị của một tín hiệu vector vào . Ví dụ viết mô tả tạo ra
dạng sóng của tín hiệu vào TestVector[3:0] nhƣ giản đồ thời gian dƣới đây:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity TestVector is
end TestVector;
architecture Behavioral of TestVector is
signal TestVector: std_logic_vector(3 downto 0):=x"0";
signal Clk: std_logic:='1';
begin
Clk<= not Clk after 10ns;
TestVectorGen:process(clk)
Begin
If(Clk'event and Clk='1') then
TestVector <= TestVector + 1;
End if;
End process;
end Behavioral;
Chương 4– Phương pháp thiết kế logic dùng VHDL
144
+ Trường hợp 6: Tạo ra tất cả các giá trị 2 tín hiệu đầu vào. Ví dụ có 2 tín hiệu đầu vào
X(1:0) và Y(1:0) nhƣ giản đồ thời gian dƣới đây:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity TwoInput is
end TwoInput;
architecture Behavioral of TwoInput is
signal X,Y: std_logic_vector(2 downto 0);
begin
double_loop: PROCESS
BEGIN
X<="000"; Y<="000";
for i in 0 to 7 loop
for j in 0 to 7 loop
wait for 10 ns;
X <= X + 1;
end loop;
Y <= Y + 1;
end loop;
END PROCESS;
end Behavioral;
b. Viết mô tả tạo thông báo
Ngoài mô tả để tạo các nguồn tín hiệu vào kích thích cho khối cần kiểm tra DUT, trong
chƣơng trình Testbench còn thực hiện các tiến trình đọc kết quả đầu ra của DUT, thực hiện
đánh giá kết quả đó hay so sánh với tín hiệu ra mong muốn để đánh giá xem thiết kế có đúng
hay không và tạo các thông báo kết quả trên màn hình. Các lệnh mô tả có thể đƣợc sử dụng
nhƣ sau:
+ Lệnh “Assert”: Đây là lệnh tuần tự chỉ dùng cho mô phỏng, đƣợc dùng để viết thông
báo ra màn hình trong quá trình mô phỏng. Cú pháp lệnh “Assert” nhƣ sau:
[Nhãn:] ASSERT boolean_condition -- Biểu thức boolean
-- Nếu boolean_condition=False thì thông báo sẽ được viết ra
[REPORT "message"] -- Viết thông báo "message" lên màn hình
[SEVERITY severity_level];-- Gán mức độ nghiêm trọng của lỗi, có thể gán
-- các giá trị sau (Note, Warning, Error (giá trị mặc định,nếu không có
-- biểu thức SEVERITY), Failure)
Chương 4– Phương pháp thiết kế logic dùng VHDL
145
+ Lệnh “Report”: Đây lệnh tuần tự cho phép viết thông báo ra màn hình
REPORT "message"
[SEVERITY severity_level];
Ví dụ:
VARIABLE a,b : INTEGER;
...
a:= 10;
b:= 11;
ASSERT a /= b -- Thông báo không được đưa ra vì a /= b là TRUE
REPORT "a equal b"
SEVERITY WARNING;
ASSERT a = b -- Sẽ có thông báo là WARNING và "a not equal b"
REPORT "a not equal b"
SEVERITY WARNING;
ASSERT a = b
REPORT "a not equal b"; -- Sẽ có thông báo là "a not equal b"
ASSERT a = b; -- Sẽ có thông báo là ERROR và "Assertion violation"
REPORT "Initialization complete";
-- Thông báo ở màn hình "Initialization complete"
REPORT "Current time = "& time'image(now);
REPORT "Incorrect branch" SEVERITY error;
Ví dụ Testbech tạo các thông báo:
entity Msg is
end Msg;
architecture Behavioral of Msg is
signal clk : std_logic := '0';
begin
clk <= not clk after 100 ns;
process
begin
wait for 1000 ns;
report "Initialization complete";
report "Current time = " & time'image(now);
wait for 1000 ns;
report "SIMULATION COMPLETED" severity failure;
end process;
end Behavioral;
Kết quả chạy mô phỏng ngoài giản đồ thời gian có có thông báo xuất hiện ở cửa sổ
Console trong màn hình Transcript của chƣơng trình mô phỏng (ISE Simulator).
Chương 4– Phương pháp thiết kế logic dùng VHDL
146
Ví dụ: Viết testbench đầy đủ kiểm tra mạch giải mã BCD-7Segments :
-- Mô tả khối giải mã BCD-7Seg cho LED 7 đoạn Anot chung:
entity BCDto7Seg is
Port ( BCD : in STD_LOGIC_VECTOR (3 downto 0);
Seg : out STD_LOGIC_VECTOR (6 downto 0));
end BCDto7Seg;
architecture Behavioral of BCDto7Seg is
begin
with BCD select
--abcdefg
Seg<="0000001" when X"0",
"1001111" when X"1",
"0010010" when X"2",
"0000110" when X"3",
"1001101" when X"4",-- Error (g)
"0100100" when X"5",
"0100000" when X"6",
"0001111" when X"7",
"0000000" when X"8",
"0000100" when X"9",
"1111110" when others;
end Behavioral;
Viết mô tả testbench đầy đủ kiểm tra BCDto7Seg
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
Chương 4– Phương pháp thiết kế logic dùng VHDL
147
USE ieee.numeric_std.ALL;
ENTITY BCDto7Seg_tb IS
END BCDto7Seg_tb;
ARCHITECTURE behavior OF BCDto7Seg_tb IS
COMPONENT BCDto7Seg
PORT(
BCD : IN std_logic_vector(3 downto 0);
Seg : OUT std_logic_vector(6 downto 0)
);
END COMPONENT;
SIGNAL StimInputs: STD_LOGIC_VECTOR(3 downto 0);
SIGNAL CaptureOutputs: STD_LOGIC_VECTOR(6 downto 0);
CONSTANT PropDelay: time := 40 ns;
CONSTANT SimLoopDelay: time := 10 ns;
TYPE vector IS RECORD
bcdStimulus: STD_LOGIC_VECTOR(3 downto 0);
sevSegOut: STD_LOGIC_VECTOR(6 downto 0);
END RECORD;
CONSTANT NumVectors: INTEGER:= 10;
-- Giá trị Tín hiệu vào/ra mong muốn
TYPE vectorArray is ARRAY (0 TO NumVectors - 1) OF vector;
CONSTANT vectorTable: vectorArray := (
(bcdStimulus => "0000", sevSegOut => "0000001"),
(bcdStimulus => "0001", sevSegOut => "1001111"),
(bcdStimulus => "0010", sevSegOut => "0010010"),
(bcdStimulus => "0011", sevSegOut => "0000110"),
(bcdStimulus => "0100", sevSegOut => "1001100"),
(bcdStimulus => "0101", sevSegOut => "0100100"),
(bcdStimulus => "0110", sevSegOut => "0100000"),
(bcdStimulus => "0111", sevSegOut => "0001111"),
(bcdStimulus => "1000", sevSegOut => "0000000"),
(bcdStimulus => "1001", sevSegOut => "0000100")
);
BEGIN
uut: BCDto7Seg PORT MAP (BCD=>StimInputs,Seg=>CaptureOutputs);
LoopStim: PROCESS
BEGIN
FOR i in 0 TO NumVectors-1 LOOP
StimInputs <= vectorTable(i).bcdStimulus;
WAIT FOR PropDelay;
ASSERT CaptureOutputs = vectorTable(i).sevSegOut
REPORT "Incorrect Output"
SEVERITY error;
Chương 4– Phương pháp thiết kế logic dùng VHDL
148
WAIT FOR SimLoopDelay;
END LOOP;
WAIT;
END PROCESS;
END behavior;
Kết quả mô phỏng trên ISE 10.1:
c. Viết mô tả sử dụng TextIO
Gói TextIO chứa các thủ tục vào hàm cho phép ngƣời thiết kế đọc và ghi file text dạng
mã ASCII. Gói thủ tục chuẩn TextIO nhƣ sau:
-- textio.vhdl
library std; use std.standard.all; -- needed for bootstrap mode
package TEXTIO is
-- Type Definitions for Text I/O
type LINE is access STRING; -- a line is a pointer to a STRING value
type TEXT is file of STRING; -- a file of variable-length ASCII records
type SIDE is (RIGHT, LEFT); -- for justifying output data within fields
subtype WIDTH is NATURAL; -- for specifying widths of output fields
-- Standard Text Files
file INPUT: TEXT open READ_MODE is "STD_INPUT";
file OUTPUT: TEXT open WRITE_MODE is "STD_OUTPUT";
-- Input Routines for Standard Types
procedure READLINE (file F: TEXT; L: inout LINE);
procedure READ (L: inout LINE; VALUE: out BIT; GOOD: out BOOLEAN);
procedure READ (L: inout LINE; VALUE: out BIT);
procedure READ (L: inout LINE; VALUE: out BIT_VECTOR; GOOD: out BOOLEAN);
procedure READ (L: inout LINE; VALUE: out BIT_VECTOR);
procedure READ (L: inout LINE; VALUE: out BOOLEAN; GOOD: out BOOLEAN);
procedure READ (L: inout LINE; VALUE: out BOOLEAN);
procedure READ (L: inout LINE; VALUE: out CHARACTER; GOOD: out BOOLEAN);
procedure READ (L: inout LINE; VALUE: out CHARACTER);
procedure READ (L: inout LINE; VALUE: out INTEGER; GOOD: out BOOLEAN);
procedure READ (L: inout LINE; VALUE: out INTEGER);
procedure READ (L: inout LINE; VALUE: out REAL; GOOD: out BOOLEAN);
Chương 4– Phương pháp thiết kế logic dùng VHDL
149
procedure READ (L: inout LINE; VALUE: out REAL);
procedure READ (L: inout LINE; VALUE: out STRING; GOOD: out BOOLEAN);
procedure READ (L: inout LINE; VALUE: out STRING);
procedure READ (L: inout LINE; VALUE: out TIME; GOOD: out BOOLEAN);
procedure READ (L: inout LINE; VALUE: out TIME);
-- Output Routines for Standard Types
procedure WRITELINE (file F: TEXT; L: inout LINE);
procedure WRITE (L: inout LINE; VALUE: in BIT;
JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0);
procedure WRITE (L: inout LINE; VALUE: in BIT_VECTOR;
JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0);
procedure WRITE (L: inout LINE; VALUE: in BOOLEAN;
JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0);
procedure WRITE (L: inout LINE; VALUE: in CHARACTER;
JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0);
procedure WRITE (L: inout LINE; VALUE: in INTEGER;
JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0);
procedure WRITE (L: inout LINE; VALUE: in REAL;
JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0;
DIGITS: in NATURAL := 0);
procedure WRITE (L: inout LINE; VALUE: in STRING;
JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0);
procedure WRITE (L: inout LINE; VALUE: in TIME;
JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0;
UNIT: in TIME := ns);
-- File Position Predicates
function ENDLINE (L: in LINE) return BOOLEAN;
end TEXTIO;
Ví dụ sử dụng TextIO để viết Testbench cho bộ đếm như sau:
entity LoadCnt is
PORT (
data: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
load: IN STD_LOGIC;
clk: IN STD_LOGIC;
rst: IN STD_LOGIC;
q: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
end LoadCnt;
architecture RTL of LoadCnt is
SIGNAL cnt: STD_LOGIC_VECTOR (7 DOWNTO 0);
BEGIN
counter: PROCESS (clk, rst)
BEGIN
IF (rst = '1') THEN
cnt '0');
ELSIF (clk'event AND clk = '1') THEN
IF (load = '1') THEN
Chương 4– Phương pháp thiết kế logic dùng VHDL
150
cnt <= data;
ELSE
cnt <= cnt + 1;
END IF;
END IF;
END PROCESS;
q <= cnt;
END RTL;
+ Sử dụng TextIO để viết Testbench cho bộ đếm LoadCnt trên:
Giả sử có file lƣu các vector kiểm tra cho bộ đếm nhƣ sau:
Vectorfile.txt
#Format is Rst, Load, Data, Q
#load the counter to all 1s
0 1 11111111 11111111
#reset the counter
1 0 10101010 00000000
#now perform load/increment for each bit
0 1 11111110 11111110
0 0 11111110 11111111
#
0 1 11111101 11111101
0 0 11111101 11111110
#
0 1 11111011 11111011
0 0 11111011 11111100
#
0 1 11110111 11110111
0 0 11110111 11111000
#
0 1 11101111 11101111
0 0 11101111 11110000
#
0 1 11011111 11011111
0 0 11011111 11100000
#
0 1 10111111 10111111
0 0 10111111 11000000
#
0 1 01111111 01111111
0 0 01111111 10000000
#
#check roll-over case
0 1 11111111 11111111
0 0 11111111 00000000
#
# End vectors
+ Mô tả Testbench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
USE ieee.std_logic_textio.all;
LIBRARY std;
USE std.textio.all;
ENTITY LoadCnt_tb IS
Chương 4– Phương pháp thiết kế logic dùng VHDL
151
END LoadCnt_tb;
ARCHITECTURE behavior OF LoadCnt_tb IS
COMPONENT LoadCnt
PORT(
data : IN std_logic_vector(7 downto 0);
load : IN std_logic;
clk : IN std_logic;
rst : IN std_logic;
q : OUT std_logic_vector(7 downto 0)
);
END COMPONENT;
constant clk_period : time := 1us;
FILE vectorFile: TEXT OPEN READ_MODE is "vectorfile.txt";-- Trong cùng
-- thư mục project
SIGNAL Data: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL Load: STD_LOGIC;
SIGNAL Rst: STD_LOGIC;
SIGNAL Qout: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL Qexpected: STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL TestClk: STD_LOGIC := '0';
CONSTANT ClkPeriod: TIME := 100 ns;
BEGIN
-- Free running test clock
TestClk <= NOT TestClk AFTER ClkPeriod/2;
-- Instance of design being tested
u1: loadCnt PORT MAP (Data => Data,
load => Load,
clk => TestClk,
rst => Rst,
q => Qout
);
-- File reading and stimulus application
readVec: PROCESS
VARIABLE VectorLine: LINE;
VARIABLE VectorValid: BOOLEAN;
VARIABLE vRst: STD_LOGIC;
VARIABLE vLoad: STD_LOGIC;
VARIABLE vData: STD_LOGIC_VECTOR(7 DOWNTO 0);
VARIABLE vQ: STD_LOGIC_VECTOR(7 DOWNTO 0);
VARIABLE space: CHARACTER;
BEGIN
WHILE NOT ENDFILE (vectorFile) LOOP
Chương 4– Phương pháp thiết kế logic dùng VHDL
152
readline(vectorFile, VectorLine); -- put file data into line
read(VectorLine, vRst, good => VectorValid);
NEXT WHEN NOT VectorValid;
read(VectorLine, space);
read(VectorLine, vLoad);
read(VectorLine, space);
read(VectorLine, vData);
read(VectorLine, space);
read(VectorLine, vQ);
WAIT FOR ClkPeriod/4;
Rst <= vRst;
Load <= vLoad;
Data <= vData;
Qexpected <= vQ;
WAIT FOR (ClkPeriod/4) * 3;
END LOOP;
ASSERT FALSE
REPORT "Simulation complete"
SEVERITY NOTE;
WAIT;
END PROCESS;
-- Process to verify outputs
verify: PROCESS (TestClk)
variable ErrorMsg: LINE;
BEGIN
IF (TestClk'event AND TestClk = '0') THEN
IF Qout /= Qexpected THEN
write(ErrorMsg, STRING'("Vector failed "));
write(ErrorMsg, now);
writeline(output, ErrorMsg);
END IF;
END IF;
END PROCESS;
END;
+ Kết quả mô phỏng:
Chương 4– Phương pháp thiết kế logic dùng VHDL
153
4.3.4 Mã mô tả VHDL không tổng hợp đƣợc
VHDL là một ngôn ngữ tiêu chuẩn, đƣợc quy định trong bộ tiêu chuẩn IEEE1076. Ban
đầu VHDL ra đời chủ yếu phục vụ cho việc mô hình hóa và mô phỏng hệ thống số, sau đó
nhiều công cụ đƣợc phát triển để có thể tự động tổng hợp đƣợc mã mô tả VHDL thành mô
hình mạch số vật lý thực hoạt động theo chức năng đã mô tả. Tuy nhiên, hiện nay không phải
tất cả các cấu trúc mã VHDL theo chuẩn IEEE1076 đều có thể tổng hợp đƣợc. Các cấu trúc
mã VHDL chủ yếu đƣợc dùng để mô hình hóa (modeling) và mô phỏng, trong đó chỉ có một
số cấu trúc VHDL có thể tổng hợp đƣợc (synthesis).
Hình 4.10 – Tập con mã VHDL có thể tổng hợp đƣợc trong bộ tiêu chuẩn IEEE1076
Đa số các cấu trúc mã VHDL mô tả thiết kế theo mức RTL và các mô tả theo mô hình
cấu trúc sử dụng các cấu trúc lệnh song song và tuần tự không sử dụng mô hình thời gian trễ
đều có thể tổng hợp đƣợc. Một số cấu trúc mã VHDL mô tả theo mô hình hoạt động không sử
dụng mô hình thời gian trễ cũng có thể tổng hợp đƣợc.
Một số cấu trúc mã VHDL không tổng hợp được cần chú ý
Các cấu trúc mã VHDL không tổng hợp đƣợc vẫn có thể sử dụng trong khi mô tả
VHDL cho hệ thống cần tổng hợp, nó chủ yếu dùng cho mô phỏng và bị công cụ tổng hợp bỏ
qua.
+ Các mô hình thời gian trễ không tổng hợp đƣợc, ví dụ:
wait for 5 ns
a <= b after 10 ns
IEEE 1076
(modeling) IEEE 1076
(synthesis)
Chương 4– Phương pháp thiết kế logic dùng VHDL
154
+ Các giá trị khởi tạo trong khai báo Signal, Port, hay Variable không tổng hợp đƣợc, và
thƣờng bị các công cụ tổng hợp bỏ qua, do đó cần sử dụng các tín hiệu Set và Reset thay thế
nếu cần thiết.
+ Các lệnh Report và Assert không tổng hợp đƣợc.
+ Các phép toán của đối tƣợng kiểu số thực Real không tổng hợp đƣợc bởi các công cụ
tổng hợp hiện nay.
+ Các mô tả Flip-Flops hoạt động đồng thời ở cả sƣờn dƣơng và sƣờn âm xung Clock
hiện chƣa tổng hợp đƣợc bởi đa số các công cụ thiết kế cho CPLD/FPGA, ví dụ mô tả sau
không tổng hợp đƣợc:
PROCESS (Clk)
BEGIN
IF rising_edge(Clk) or falling_edge(CLk) THEN
Q <= D ;
END IF ;
END PROCESS ;
4.4. CÁC MÔ HÌNH TÍN HIỆU SỐ
Một số mô hình tín hiệu số dùng cho mô tả hệ thống số nhƣ sau:
+ Tín hiệu đơn
wire
a
1
SIGNAL a : STD_LOGIC;
+ Tín hiệu Bus
bus
b
8
SIGNAL b : STD_LOGIC_VECTOR(7 DOWNTO 0);
+ Ghép tín hiệu thành Bus
4
5
10
a
b
c
d
SIGNAL a: STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL b: STD_LOGIC_VECTOR(4 DOWNTO 0);
SIGNAL c: STD_LOGIC;
SIGNAL d: STD_LOGIC_VECTOR(9 DOWNTO 0);
d <= a & b & c;
+ Tách tín hiệu trong Bus
Chương 4– Phương pháp thiết kế logic dùng VHDL
155
4
5
10
a
b
c
d
-- Sử dụng phép tách
SIGNAL a: STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL b: STD_LOGIC_VECTOR(4 DOWNTO 0);
SIGNAL c: STD_LOGIC;
SIGNAL d: STD_LOGIC_VECTOR(9 DOWNTO 0);
a <= d(9 downto 6);
b <= d(5 downto 1);
c <= d(0);
-- Sử dụng Alias
SIGNAL d: STD_LOGIC_VECTOR(9 DOWNTO 0);
ALIAS a: STD_LOGIC_VECTOR(3 DOWNTO 0) IS d(9 downto 6);
ALIAS b: STD_LOGIC_VECTOR(4 DOWNTO 0) IS d(5 downto 1);
ALIAS c: STD_LOGIC IS d(0);
4.5. MÔ TẢ THEO MÔ HÌNH CẤU TRÖC
Mô hình cấu trúc là mô hình mô tả cấu trúc bên trong của hệ thống gồm các thành phần
con và các kết nối giữa chúng. Mô hình này giống nhƣ sơ đồ khối hay mạch nguyên lý của hệ
thống. Mô hình cấu trúc của một phần tử (hoặc hệ thống) có thể bao gồm nhiều cấp cấu trúc
bắt đầu từ một cổng logic đơn giản đến xây dựng mô tả cho một hệ thống hoàn thiện.
Sử dụng VHDL mô tả hệ thống theo mô hình cấu trúc có thể thực hiện theo 2 cách sau:
+ Cách thứ nhất đó là mô tả theo mô hình cấu trúc đƣợc phân tách bởi các cấu trúc lệnh
khác nhau dùng trong cùng một file mô tả VHDL. Các tín hiệu đƣơc sử dụng chung phù hợp
giữa các cấu trúc lệnh tạo ra sự kết nối giữa các khối con đƣợc mô tả bởi các cấu trúc lệnh đó.
+ Cách thứ hai là mỗi khối con sẽ đƣợc mô tả bởi một thực thể riêng, sau đó sử dụng
lệnh component để khai báo các thực thế con đó cho thiết kế, và dùng lệnh port map để gọi
và chọn mỗi khối con component và thực hiện kết nối các khối con đó với nhau tạo ra hệ
thống cần mô tả.
Một số lƣu ý trong việc phân chia hệ thống thành các khối con:
- Tối thiểu hóa số xung nhip Clock của mối khối: Rất quan trọng cho việc tối ƣu và thực
hiện những ràng buộc về định thời.
- Nên sử dụng thanh ghi để đệm tín hiệu ra mỗi mô-đun: Phù hợp với mô hình RTL.
- Giữ những tín hiệu quan trọng trong một khối.
- Tách thành các khối đủ nhỏ để việc kiểm tra nhanh và dễ dàng, việc viết testbench cho
mỗi khối con cũng đơn giản hơn.
- Kích thƣớc của các khối phù hợp để việc tổng hợp tối ƣu và có thể độc lập với công
nghệ và công cụ.
Ví dụ: Thiết kế và mô tả VHDL cho bộ ALU có chức năng nhƣ bảng sau:
Chương 4– Phương pháp thiết kế logic dùng VHDL
156
Sel Phép toán không dấu Khối (Unit) Sel Phép toán Khối (Unit)
0000
0001
0010
0011
0100
0101
0110
0111
y <= a
y <= a+1
y <= a-1
y <= b
y <= b+1
y <= b-1
y <= a+b
y <= a+b+cin
Arithmetic
1000
1001
1010
1011
1100
1101
1110
1111
y <= NOT a
y <= NOT b
y <= a AND b
y <= a OR b
y <= a NAND b
y <= a NOR b
y <= a XOR b
y <= a XNOR b
Logic
Nhƣ vậy bộ ALU có chức năng thực hiện nhiều phép toán số học và logic, các phép