Mục đích
Viết mô tả và kiểm tra cho khối dịch bằng các phương pháp khác
nhau: bằng toán tử dịch, bằng sơ đồ thuật toán dịch. Các tạo nhiều giá
trị kiểm tra bằng mã VHDL, cách viết và sử dụng thực thể có nhiều kiến
trúc.
10 trang |
Chia sẻ: hoang10 | Lượt xem: 680 | Lượt tải: 0
Bạn đang xem nội dung tài liệu Thực hành: Thiết kế logic số - Bài 03: Khối dịch và thanh ghi dịch, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
Khoa Vô tuyến điện tử
Bộ môn Kỹ thuật Xung, số, VXL
Thực hành: Thiết kế logic số
Bài 03: Khối dịch và thanh ghi dịch
Mục đích
Viết mô tả và kiểm tra cho khối dịch bằng các phương pháp khác
nhau: bằng toán tử dịch, bằng sơ đồ thuật toán dịch. Các tạo nhiều giá
trị kiểm tra bằng mã VHDL, cách viết và sử dụng thực thể có nhiều kiến
trúc.
Công cụ phục vụ thực hành : Máy vi tính
Thời gian : 1h30
1. Khối dịch dùng toán tử dịch
Các phép toán quan hệ gồm sll, srl, sla, sra, rol, ror được
hỗ trợ trong thư viện ieee.numeric_bit, và ieee.numeric_std. Cú pháp của các
lệnh dịch có hai tham số là sho (shift operand) và shv (shift value), ví dụ cú
pháp của sll như sau
sha sll shv;
Toán
tử
Phép toán Kiểu của sho Kiểu của
shv
Kiểu kết quả
sll Dịch trái logic Mảng 1 chiều kiểu BIT hoặc
BOOLEAN
Integer Cùng kiểu sho
srl Dịch phải logic Mảng 1 chiều kiểu BIT hoặc
BOOLEAN
Integer Cùng kiểu sho
sla Dịch trái số học Mảng 1 chiều kiểu BIT hoặc
BOOLEAN
Integer Cùng kiểu sho
sra Dịch phải số học Mảng 1 chiều kiểu BIT hoặc
BOOLEAN
Integer Cùng kiểu sho
rol Dịch vòng tròn
sang trái
Mảng 1 chiều kiểu BIT hoặc
BOOLEAN
Integer Cùng kiểu sho
ror Dịch vòng tròn
phải
Mảng 1 chiều kiểu BIT hoặc
BOOLEAN
Integer Cùng kiểu sho
Đối với dich logic thì tại các vị trí bị trống sẽ được điền vào các giá trị ‘0’
còn dịch số học thì các các vị trí trống được thay thế bằng bit có trọng số cao
nhất MSB nếu dịch phải, và thay bằng bit có trọng số thấp nhất nếu dịch trái.
Đối với dịch vòng thì các vị trí khuyết đi sẽ được điền bằng các bit dịch ra ngoài
giới hạn của mảng. Quan sát ví dụ dưới đây
# sho = 11000110
# sho sll 2 = 00011000
# sho srl 2 = 00110001
# sho sla 2 = 00011000
# sho sra 2 = 11110001
# sho rol 2 = 00011011
# sho ror 2 = 10110001
Bước 1: Viết cho khối dịch logic phải.
Hướng dẫn: (file mô tả có tên shifter.vhd) Sơ đồ khối của khối dịch như sau:
SHIFTER
Shift_in
Shift_value
Toán tử dịch có cấu trúc:
Shift_out = Shift_in sll shift_value;
Trong đó bắt buộc shift_in và shift_out có kiểu BIT_VECTOR, còn shift_value có
kiểu INTEGER.
Trên thực tế các đầu vào này cần được khai báo dạng STD_LOGIC_VECTOR để
tương thích với các khối khác do vậy có các hàm chuyển đổi sau:
TO_BITVECTOR(shift_in) - chuyển sang kiểu BIT_VECTOR;
CONV_INTEGER(„0‟ & shift_value) – chuyển sang kiểu INTEGER;
TO_STDLOGICVECTOR(sho) – chuyển ngược lại STD_LOGIC_VECTOR;
Chú ý rằng khi chuyển sang kiểu INTEGER cần thêm bit 0 đằng trước để lấy
đúng giá trị biểu diễn không dấu của giá trị dịch.
Khi đó buộc phải khai báo thư viện như sau:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
USE ieee.Numeric_STD.all;
USE ieee.Numeric_BIT.all;
Với các tín hiệu dầu vào là STD_LOGIC_VECTOR ta phải khai báo các tín
hiệu trung gian kiểu tương thích với lệnh dịch ở phần khai báo kiến trúc:
signal shi: bit_vector(31 downto 0);
signal sho: bit_vector(31 downto 0);
signal sa : integer;
Dựa trên hướng dẫn trên viết khối dịch dùng toán tử cho phép dịch phải
cho chuỗi 32-bit đầu vào.
Bước 2: Viết module kiểm tra cho khối dịch ở bước 1.
Hướng dẫn: Ở bài thực hành trước chúng ta quen với cách kiểm tra nhanh với
1 tổ hợp đầu vào. Ở bài này sẽ làm quen với phương pháp kiểm tra nhanh cho
một số tổ hợp giá trị đầu vào. Để làm được như cần bổ xung vào phần mô tả
kiến trúc của khối kiểm tra đoạn mã tạo các dữ liệu đầu vào bằng lệnh wait for.
Ví dụ như sau:
create_data: process
begin
shift_in <= x"19107111" after 50 ns;
shift_value <= "00011";
wait for 150 ns;
shift_in <= x"19107000" after 50 ns;
shift_value <= "00111";
wait for 170 ns;
shift_in <= x"1abc7111" after 50 ns;
shift_value <= "00011";
wait;
end process create_data;
Đoạn mã trên gán các giá trị khác nhau cho các đầu vào khác nhau,
tương ứng trên giản đồ sóng sẽ quan sát được sự thay đổi này.
Bước 3: Viết mô tả khối dịch có kiến trúc mà không sử dụng thuật toán dịch.
Hướng dẫn: Một thực thể có thể có nhiều kiến trúc và các kiến trúc có thể được mô
tả độc lập với nhau trong 1 mô tả VHDL. Cụ thể ở bước này cần bổ xung vào file
nguồn tạo ở bước 1 mô tả kiến trúc thứ hai bắt đầu bằng architecture (phần in đậm
cuối file)
-- HVKTQS - VTDT - KT vixuly
-- SHIFTER
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_arith.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
USE ieee.Numeric_STD.all;
USE ieee.Numeric_BIT.all;
-----------------------------------------
entity shifter_32 is
port(
shift_in : in std_logic_vector(31 downto 0);
shift_value: in std_logic_vector(4 downto 0);
shift_out : out std_logic_vector(31 downto 0)
);
end shifter_32;
-- khoi dich su dung toan tu dich
architecture behavioral of shifter_32 is
begin
...
--Mo ta kien trúc 1
end behavioral;
-- khoi dich su dung thuat toan dich don gian
architecture rtl of shifter_32 is
Begin
--mota kien trúc 2
end rtl;
Thuật toán dịch không sử dụng toán tử dịch như sau:
Nhận xét rằng độ phức tạp của khối dịch trên nằm ở chỗ giá trị dịch là không
xác định, nếu giá trị dịch xác định thì phép dịch có thể thực hiện hết sức dễ
dàng bằng toán tử hợp &. Ví dụ để dịch chuỗi bit đi 4 bit logic sang phải
shift_out = “0000” & shift_in(31 downto 4);
Từ đó có thể xây dựng khối dịch bằng sơ đồ thuật toán đơn giản như
sau. Giả sử ta cần thiết kế khối dịch cho dữ liệu dịch shift_in 32 bit, giá trị dịch
shift_value được biểu diễn là 5 bit. Các bit của shift_value từ cao nhất tới thấp
nhất sẽ được xét. Ví dụ, với bit đầu tiên shift_value(4) được đưa vào làm tín
hiệu điều khiển cho khối chọn kênh thứ nhất, nếu shift_value(4) = 1 giá trị
được chọn sẽ là đầu vào shift_in được dịch đi 16 bit bởi bộ dịch SH16, nếu
shift_value(4) = 0 thì giá trị shift_in được chọn, nghĩa là đầu vào không bị dịch
đi. Sơ đồ cứ tiếp tục như vậy cho đến bit cuối cùng shift_value(0), đầu ra của
khối chọn kênh cuối cùng chính là giá trị shift_out.
SH16
Shift_value(4)
Shift_in
Shift16
Shift_in4
SH8
Shift_value(3)
Shift8
Shift_in3
SH4
Shift_value(2)
Shift4
Shift_in2
SH2
Shift_value(1)
Shift2
Shift_in1
SH1
Shift_value(0)
Shift1
Shift_out
Sơ đồ thuật toán khối dịch đơn giản
Để hiện thực sơ đồ trên bằng VHDL ta sử dụng cấu trúc câu lệnh song song
WITH/SELECT. Trước hết cần khai báo trong khai báo kiến trúc các tín hiệu trung
gian shift_in4, shift_in3,
signal shift_in4 : std_logic_vector(31 downto 0);
signal shift_in3 : std_logic_vector(31 downto 0);
signal shift_in2 : std_logic_vector(31 downto 0);
signal shift_in1 : std_logic_vector(31 downto 0);
signal shift_in0 : std_logic_vector(31 downto 0);
Sau đó cho mỗi bước dịch trên ta sử dụng câu lệnh WITH/SELECT
with shift_value(4) select
shift_in4 <= x"0000" & shift_in(31 downto 16) when '1',
shift_in when others;
Bước 4: Viết Kiểm tra đồng thời cho hai kiến trúc của khối dịch đã mô tả ở bước 3.
Hướng dẫn:
Vì ở trên khối dịch có hai kiến trúc nên để kiểm tra khối dịch ta sẽ cài đặt cả hai
kiến trúc này trong khối kiểm tra( trong phần mô tả kiến trúc), lưu ý rằng các
đầu vào của các khối dịch với kiến trúc khác nhau có thể dùng chung nhưng
đầu ra tuyệt đối phải khác nhau. Ở đây ta khai báo hai đầu ra là shift_out0,
shift_out1.
sh320: component shifter_32 port map (shift_in,
shift_value, shift_out0);
sh321: component shifter_32 port map (shift_in,
shift_value, shift_out1);
Tuy vậy để xác định kiến trúc nào sẽ được mô phỏng ta phải có mã quy định
trước trong phần khai báo kiến trúc như sau:
for sh320: shifter_32 use entity
work.shifter_32(behavioral);
for sh321: shifter_32 use entity work.shifter_32(rtl);
Với quy định trên thì khối con sh320 dùng kiến trúc behavioral còn khối
sh321 dùng kiến trúc rtl.
Mô phỏng kiểm tra sẽ thu được kết quả là các kiến trúc khác nhau thực
hiện chức năng giống nhau, ví dụ kết quả như hình sau:
2. Thanh ghi
Bước 5: Viết mô tả cho thanh ghi N- bit có cấu trúc và giản đồ sóng như:
Hướng dẫn: Thanh ghi N-bit cần khai báo N là tham biến tĩnh Generic.
Tín hiệu RESET ở đây là tín hiệu RESET không đồng bộ, còn tín hiệu CLK kích hoạt
tại sườn dương. Thanh ghi viết buộc phải dùng cấu trúc IF/THEN trong khối lệnh
tuần tự (khối PROCESS).
if RESET = '1' then
Q '0');
elsif CLK = '1' and CLK'event then
Q <= D;
end if;
Ý nghĩa của lệnh Q '0'); là gán tất cả các bit của Q giá trị bằng 0.
Bước 6: Mô phỏng kiểm tra thanh ghi, nhận xét về sự thay đổi dữ liệu trên
thanh ghi và so sánh với các khối tổ hợp mô tả trước đó.
Hướng dẫn: Khác với các khối tổ hợp thanh ghi là mạch dãy do đó khi kiểm tra cần
tạo đúng dạng cho xung nhịp CLK.
Để tạo xung nhịp CLK dùng một khối process không có danh sách sensitive
list, trong đó ta dùng một lệnh wait for để tránh cảnh báo khi biên dịch về việc thiếu
danh sách sensitive list. Tín hiệu CLK sẽ được gán bằng đảo của nó sau mỗi nửa
chu kỳ. Chú ý rằng con số chỉ thời gian ở đây có thể bất kỳ vì chỉ sử dụng cho mô
phỏng.
--create clock
create_clock: process
begin
wait for 15 ns;
CLK <= not CLK after 50 ns;
end process create_clock;
Tín hiệu RESET và dữ liệu đầu vào D được tạo bằng lệnh Wait for trong
một khối khác, ví dụ như sau:
reset <= '0'; enable <= '1';
wait for 10 ns;
reset <= '1';
D <= x”923856c8”;
wait for 100 ns;
reset <= '0';
D <= x”10245608”;
wait for 250 ns;
D <= x”a23400a8”;
wait for 200 ns;
D <= x”c00456c8”;
wait;
Bước 7: Viết mô tả cho thanh ghi dịch phải số học.
Hướng dẫn: Kết hợp khối dịch phải số học và thanh ghi ta được cấu trúc của
thanh ghi dịch phải số học như ở hình sau:
REG1
Q
clk, reset Shift_value
SHIFTER
MUX
WE Shift_in
Shift_out
D
Hình 2.17: Sơ đồ thuật toán khối dịch đơn giản
Thanh ghi có thể làm việc ở hai chế độ, chế độ thứ nhất dữ liệu đầu vào
được lấy từ đầu vào D nếu tín hiệu WE = 1, chế độ thứ hai là chế độ dịch, khi
đó dữ liệu đầu vào của thanh ghi lấy từ khối dịch khi WE = 0, đầu ra của thanh
ghi được gán bằng đầu vào của khối dịch. Ở chế độ này dữ liệu sẽ bị dịch liên
tục mỗi xung nhịp một lần.
Để viết thanh ghi dịch thì ta viết mô tả của khối dịch, của khối MUX và
thanh ghi riêng sau đó ghép lại. Đối với khối dịch sử dụng kiến trúc dịch dùng
thuật toán.
Ví dụ giản đồ sóng sau là của thanh ghi dịch trái logic: