Thực hành Thiết kế logic - Bài 3: Khối dịch và thanh ghi dịch
Bạn đang xem tài liệu "Thực hành Thiết kế logic - Bài 3: Khối dịch và thanh ghi dịch", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- thuc_hanh_thiet_ke_logic_bai_3_khoi_dich_va_thanh_ghi_dich.pdf
Nội dung text: Thực hành Thiết kế logic - Bài 3: Khối dịch và thanh ghi dịch
- 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 Phép toán Kiểu của sho Kiểu của Kiểu kết quả tử shv sll Dịch trái logic Mảng 1 chiều kiểu BIT hoặc Integer Cùng kiểu sho BOOLEAN srl Dịch phải logic Mảng 1 chiều kiểu BIT hoặc Integer Cùng kiểu sho BOOLEAN sla Dịch trái số học Mảng 1 chiều kiểu BIT hoặc Integer Cùng kiểu sho BOOLEAN sra Dịch phải số học Mảng 1 chiều kiểu BIT hoặc Integer Cùng kiểu sho BOOLEAN rol Dịch vòng tròn Mảng 1 chiều kiểu BIT hoặc Integer Cùng kiểu sho sang trái BOOLEAN ror Dịch vòng tròn Mảng 1 chiều kiểu BIT hoặc Integer Cùng kiểu sho phải BOOLEAN Đố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:
- Shift_in Shift_value SHIFTER 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.
- Shift_in SH16 Shift16 Shift_value(4) Shift_in4 SH8 Shift8 Shift_value(3) Shift_in3 SH4 Shift4 Shift_value(2) Shift_in2 SH2 Shift2 Shift_value(1) Shift_in1 SH1 Shift1 Shift_value(0) 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 '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: clk, reset WE D Shift_value Shift_in SHIFTER Shift_out MUX REG1 Q 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: