Giáo trình Thiết kế logic số
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Thiết kế logic số", để 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:
- giao_trinh_thiet_ke_logic_so.pdf
Nội dung text: Giáo trình Thiết kế logic số
- HỌC VIỆN KỸ THUẬT QUÂN SỰ BỘ MÔN KỸ THUẬT XUNG SỐ, VI XỬ LÝ – KHOA VÔ TUYẾN ĐIỆN TỬ THIẾT KẾ LOGIC SỐ (Dùng cho đối tƣợng đào tạo chính quy hệ quân sự và dân sự) LƢU HÀNH NỘI BỘ HÀ NỘI -2011 1
- LỜI GIỚI THIỆU Thiết kế logic số là môn học kế tiếp của chƣơng trình Điện tử số. Nội dung chính của chƣơng trình môn học tập trung vào hai vấn đề kiến thức chính. Thứ nhất là bài toán thiết kế về mặt chức năng cho các khối số có mật độ tích hợp lớn cỡ LSI, VLSI và lớn hơn. Vấn đề thứ hai là giới thiệu căn bản về các công nghệ giúp hiện thực hóa thiết kế chức năng thành sản phẩm ứng dụng, trong đó tập trung chính vào công nghệ FPGA, một nền tảng công nghệ mới đã và đang phát triển rất mạnh hiện nay. Khác với bài toán tổng hợp và phân tích trong Điện tử số chủ yếu là bài toán cho các mạch cỡ SSI, MSI, các bài toán ở đây có hƣớng tới các ứng dụng cụ thể thực tiễn với quy mô lớn hơn và buộc phải sử dụng các công cụ trợ giúp thiết kế trên máy tính và ngôn ngữ thiết kế VHDL Chƣơng trình Thiết kế logic số nhắm vào trang bị kiến thức cơ sở ngành cho tất cả các đối tƣợng sinh viên thuộc chuyên ngành kỹ thuật Điện tử viễn thông, Điều khiển tự động. Trƣớc khi học môn này các sinh viên này phải học qua các môn cơ sở ngành gồm Cấu kiện điện tử, Điện tử số, Kỹ thuật Vi xử lý trong đó hai môn đầu là bắt buộc. Thiết kế logic số là một môn học mang tính thực hành cao nên trong cấu trúc chƣơng trình sẽ dành nhiều thời gian hơn cho thực hành thí nghiệm cũng nhƣ bắt buộc sinh viên khi kết thúc môn học phải thực hiện các đồ án bài tập thiết kế cỡ vừa và lớn theo nhóm dƣới dạng Bài tập lớn hoặc Đồ án môn học. Kiến thức và kỹ năng của sinh viên sẽ giúp ích rất lớn cho các bài toán chuyên ngành và Đồ án tốt nghiệp sau này bởi trong các ứng dụng xử lý số đang dần chiếm vai trò quan trọng trong các hệ thống kỹ thuật. Bên cạnh những công cụ truyền thống là Vi xử lý, máy tính thì thiết kế phần cứng trên FPGA hoặc trên nền các công nghệ tƣơng tự đang là một hƣớng phát triển mang lại hiệu năng vƣợt trội và khả năng ứng dụng thích nghi tốt hơn. Giáo trình chính thức cho môn học đƣợc hoàn thiện sau hơn 2 khóa đào tạo cho sinh viên hệ đào tạo dân sự, quân sự tại Học viện Kỹ thuật quân sự. Nhóm tác giả xin chân thành cám ơn sự ủng hộ nhiệt tình của lãnh đạo Khoa Vô tuyến điện tử, lãnh đạo bộ môn Kỹ thuật xung số, vi xử lý, các đồng nghiệp trong khoa và bộ môn đã có nhiều ý kiến đóng góp quý báu góp phần hoàn thiện nội dung cho giáo trình, cám ơn anh chị em nhân viên của bộ môn đã góp nhiều công sức cho công việc chế bản cho giáo trình. Nhóm tác giả cũng gửi lời cám ơn tới 3
- toàn bộ các sinh viên các khóa đào tạo bằng quá trình học tập, nghiên cứu thực tế đã có những ý kiến đóng góp giúp tác giả điều chỉnh về khung chƣơng trình và nội dung ngày hợp lý và hiệu quả hơn. Vì thời gian hạn chế và là một môn học mới do vậy chắc chắn sẽ còn nhiều những khiếm khuyết trong giáo trình. Nhóm tác giả rất mong tiếp tục nhận đƣợc những ý kiến đóng góp của ngƣời sử dụng, mọi ý kiến có thể gửi về Bộ môn Kỹ thuật Xung số, Vi xử lý – Học viện KTQS hoặc vào hòm thƣ điện tử quangkien82@gmail.com. Hà nội 12-2011 4
- Mục lục LỜI GIỚI THIỆU 3 DANH SÁCH CÁC KÝ HIỆU VIẾT TẮT 11 Chƣơng 1: CÁC KIẾN THỨC CƠ SỞ 15 1. Các khái niệm chung 16 1.1. Transitor 16 1.2. Vi mạch số tích hợp 17 1.3. Cổng logic 18 1.4. Phần tử nhớ 20 1.5 Mạch logic tổ hợp 23 1.6. Mạch logic tuần tự 24 1.7 Các phƣơng pháp thể hiện thiết kế. 25 2. Yêu cầu đối với một thiết kế logic 27 3. Các công nghệ thiết kế mạch logic số 28 4. Kiến trúc của các IC khả trình 31 4.1. Kiến trúc PROM, PAL, PLA, GAL 31 4.2. Kiến trúc CPLD, FPGA 36 Câu hỏi ôn tập chƣơng 1 39 Chƣơng 2: NGÔN NGỮ MÔ TẢ PHẦN CỨNG VHDL 41 1. Giới thiệu về VHDL 42 2. Cấu trúc của chƣơng trình mô tả bằng VHDL 43 2.1. Khai báo thƣ viện 44 2.2. Mô tả thực thể 45 2.3. Mô tả kiến trúc 48 2.4. Khai báo cấu hình 53 3. Chƣơng trình con và gói 56 5
- 3.1. Thủ tục 56 3.2. Hàm 58 3.3. Gói 59 4. Đối tƣợng dữ liệu, kiểu dữ liệu 62 4.1. Đối tƣợng dữ liệu 62 4.2. Kiểu dữ liệu 63 5. Toán tử và biểu thức 70 5.1. Toán tử logic 70 5.2. Các phép toán quan hệ 71 5.3. Các phép toán dịch 72 5.4. Các phép toán cộng trừ và hợp 74 5.5. Các phép dấu 74 5.6. Các phép toán nhân chia, lấy dƣ 75 5.7. Các phép toán khác 76 6. Phát biểu tuần tự 76 6.1. Phát biểu đợi 76 6.2. Phát biểu xác nhận và báo cáo 79 6.3. Phát biểu gán biến 80 6.4. Phát biểu gán tín hiệu 81 6.5. Lệnh rẽ nhánh và lệnh lặp 83 7. Phát biểu đồng thời 87 7.1. Phát biểu khối 88 7.2. Phát biểu quá trình 89 7.3. Phát biểu gán tín hiệu đồng thời 92 7.4. Phát biểu generate 95 7.5. Phát biểu cài đặt khối con 97 8. Phân loại mã nguồn VHDL 99 9. Kiểm tra thiết kế bằng VHDL. 101 6
- 9.1. Kiểm tra nhanh 102 9.1. Kiểm tra tự động nhiều tổ hợp đầu vào 104 Bài tập chƣơng 2 111 Bài tập 111 Câu hỏi ôn tập lý thuyết 116 Chƣơng 3: THIẾT KẾ CÁC KHỐI MẠCH DÃY VÀ TỔ HỢP THÔNG DỤNG 117 1. Các khối cơ bản 118 1.1. Khối cộng đơn giản 118 1.2. Khối trừ 119 1.3. Khối cộng thấy nhớ trƣớc. 121 1.4. Thanh ghi 125 1.5. Bộ cộng tích lũy 127 1.6. Bộ đếm 129 1.7. Bộ dịch 131 1.8. Thanh ghi dịch 133 2. Các khối nhớ 136 2.1. Bộ nhớ RAM 136 2.2. Bộ nhớ ROM 139 2.3. Bộ nhớ FIFO 141 2.4. Bộ nhớ LIFO 142 3. Máy trạng thái hữu hạn 143 4. Khối nhân số nguyên 145 4.1. Khối nhân số nguyên không dấu dùng phƣơng pháp cộng dịch 146 4.2. Khối nhân số nguyên có dấu 150 4.3. Khối nhân dùng mã hóa Booth cơ số 4 155 5. Khối chia số nguyên 158 5.1. Khối chia dùng sơ đồ khôi phục phần dƣ 159 7
- 5.2. Khối chia dùng sơ đồ không khôi phục phần dƣ 162 5.3. Khối chia số nguyên có dấu 164 6. Các khối làm việc với số thực 169 6.1. Số thực dấu phẩy tĩnh 169 6.2. Số thực dấu phẩy động 170 6.3. Chế độ làm tròn trong số thực dấu phẩy động. 173 6.4. Phép cộng số thực dấu phẩy động 176 6.5. Phép nhân số thực dấu phẩy động 181 6.6. Phép chia số thực dấu phẩy động 183 Bài tập chƣơng 3 186 Bài tập 186 Câu hỏi ôn tập lý thuyết 194 Chƣơng 4: THIẾT KẾ MẠCH SỐ TRÊN FPGA 195 1. Tổng quan về kiến trúc FPGA 196 1.2. Khái niệm FPGA 196 1.3. Ứng dụng của FPGA trong xử lý tín hiệu số 198 1.4. Công nghệ tái cấu trúc FPGA 199 1.5. Kiến trúc tổng quan 200 2. Kiến trúc chi tiết Xilinx FPGA Spartan-3E. 201 2.1. Khối logic khả trình 204 2.2. Khối điều khiển vào ra 221 2.3. Hệ thống kết nối khả trình 224 2.4. Các phần tử khác của FPGA 227 3. Quy trình thiết kế FPGA bằng ISE 237 3.1. Mô tả thiết kế 238 3.2. Tổng hợp thiết kế 239 3.3. Hiện thực hóa thiết kế 244 3.4. Cấu hình FPGA 250 8
- 3.5. Kiểm tra thiêt kế trên FPGA 250 4. Một số ví dụ thiết kế trên FPGA bằng ISE 251 4.1. Thiết kế khối nhận thông tin UART 253 4.2. Thiết kế khối điều khiển PS/2 cho Keyboard, Mouse 267 4.3. Thiết kế khối tổng hợp dao động số NCO 270 4.4. Thiết kế khối điều khiển LCD1602A 282 4.5. Thiết kế điều khiển VGA trên FPGA. 294 Bài tập chƣơng 4 308 1. Bài tập cơ sở 308 2. Bài tập nâng cao 309 3. Câu hỏi ôn tập lý thuyết 312 PHỤ LỤC 313 Phụ lục 1: THỐNG KÊ CÁC HÀM, THỦ TỤC, KIỂU DỮ LIỆU CỦA VHDL TRONG CÁC THƢ VIỆN CHUẨN IEEE. 314 1. Các kiểu dữ liệu hỗ trợ trong các thƣ viện chuẩn IEEE 314 2. Các hàm thông dụng hỗ trợ trong các thƣ viện chuẩn IEEE 315 3. Các hàm phục vụ cho quá trình mô phỏng kiểm tra thiết kế 319 4. Các hàm biến đổi kiểu dữ liệu dùng trong VHDL 322 Phụ lục 2: THỰC HÀNH THIẾT KẾ VHDL 325 Bài 1: Mô phỏng VHDL trên ModelSim 326 Bài 2: Xây dựng bộ cộng trừ trên cơ sở khối cộng bằng toán tử 338 Bài 3: Khối dịch và thanh ghi dịch 344 Bài 4: Bộ cộng bit nối tiếp dùng 1 FA (serial-bit adder) 353 Phụ lục 3: MẠCH PHÁT TRIỂN ỨNG DỤNG FPGA 364 1. Giới thiệu tổng quan 364 2. Các khối giao tiếp có trên mạch FPGA 366 2.4. Khối giao tiếp Keypad 367 2.5. Khối 8x2 Led-Diod 367 9
- 2.6. Khối Switch 367 2.7. Khối giao tiếp 4x7-seg Digits 367 2.9. Khối giao tiếp USB 368 2.10. Khối giao tiếp PS/2 368 Phụ lục 4: THỰC HÀNH THIẾT KẾ MẠCH SỐ TRÊN FPGA 371 Bài 1: Hƣớng dẫn thực hành FPGA bằng Xilin ISE và Kit SPARTAN 3E 372 Bài 2: Thiết kế khối giao tiếp với 4x7Seg -digits 397 Phụ lục 5: CÁC BẢNG MÃ THÔNG DỤNG 407 1. Mã ASCII điều khiển 408 2. Mã ASCII hiển thị 410 3. Bảng mã ký tự cho LCD 1602A 414 TÀI LIỆU THAM KHẢO 415 10
- DANH SÁCH CÁC KÝ HIỆU VIẾT TẮT AES : Advance Encryption Standard Thuật toán mã hóa AES ALU : Arithmetic Logic Unit Khối thực thi số học logic ASIC : Aplication Specific Intergrated Vi mạch tích hợp với chức năng Circuit chuyên dụng. BJT : Bipolar Junction Transitor Transitor lƣỡng cực BRAM : Block RAM Khối nhớ truy cập ngẫu nhiên trong FPGA CLA : Carry Look-Ahead Adder Khối cộng thấy nhớ trƣớc CLB : Configurable Logic Block Khối Logic khả trình trong FPGA CMOS : CMOS (Complementary- Công nghệ bán dẫn dùng trên Symmetry Metal-Oxide cặp bù PN transitor trƣờng. Sermiconductor) CPLD : Complex Programmable Logic Vi mạch khả trình phức tạp( cỡ Device lớn) DCM : Digital Clock Manager Khối quản lý và điều chỉnh xung nhịp hệ thống trong FPGA DDR : Double Data Rate Truyền dữ liệu với tốc độ gấp đôi tốc độ cung nhịp hệ thống DES : Data Encryption Standard Thuật toán mã hóa DES DFS : Digital Frequency Synthesis Khối tổng hợp tần số DLL : Delay Locked Loop Khối lặp khóa trễ DRAM : Dynamic RAM RAM động DRC : Design Rule Check Kiểm tra các vi phạm trong thiết kế DUT : Device Under Test Đối tƣợng đƣợc kiểm tra E2PROM : Electric-Eraseable Programmable PROM có thể xóa bằng điện ROM EDIF : Electronic Design Interchange Chuẩn công nghiệp để mô tả Format các khối điển tử. EDK :Embbed Develovepment Kit Tổ hợp phần mềm thiết kế hệ nhúng trên FPGA 11
- EPROM : Eraseable Programmable ROM PROM có thể xóa đựoc F5MUX : Wide-Multiplexer Khối chọn kênh mở rộng trong FPGA FET : Field Effect Transitors Transitor dùng hiệu ứng trƣờng FIFO : First In First Out Bộ nhớ có dữ liệu vào trƣớc sẽ đƣợc đọc ra trƣớc. FiMUX : Wide-Multiplexer Khối chọn kênh mở rộng trong FPGA FPGA : Field-Programmable Gate Array IC khả trình cấp độ ngƣời dùng cuối FPU : Floating Point Unit Khối xử lý số thực dấu phẩy động GAL : Generic Array Logic IC khả trình trên công nghệ CMOS HDL : Hardware Description Language Ngôn ngữ mô tả phần cứng I2C : Inter-Integrated Circuit Giao tiếp I2C truyền dữ liệu giữa các IC IC : Integrated Circuit Vi mạch tích hợp IEEE : Institute of Electrical and Viện kỹ thuật Điện và Điện tử Electronics Engineers IOB : Input/Output Buffer Khối đệm vào ra trong FPGA IP Core : Intellectual Property core Thiết kế đƣợc đăng ký sở hữu trí tuệ ISE : Integrated Software Enviroment Tổ hợp phần mềm thiết kế FPGA của Xilinx LIFO : Last In First Out Khối nhớ LIFO, dữ liệu vào sau cùng sẽ ra trƣớc nhất LSI : Large scale integration Vi mạch tích hợp cỡ lớn LUT : Look-Up Table Bảng tham chiếu trong FPGA MOSFET : Metal-oxide-sermiconductor Transitor trƣờng dùng tiếp giáo Field-Effect-Transitors kim loại – bán dẫn MSI : Medium scale integration Vi mạch tích hợp cỡ trung MULT18 : Dedicated Multiplier 18 x18 Khối nhân chuyên dụng trong FPGA NCD : Native Circuit Database Định dạng sau quá trình Ánh xạ 12
- cổng và Sắp đặt kết nối của Xilinx ISE. NCF : Native Constraint File Tệp cài đặt điều kiện ràng buộc cơ bản của thiết kế. NGD : Native Generic Database Định dạng sau quá trình Translate của Xilinx ISE PAL : Programmable Array Logic Mảng logic khả trình PAR : Place and Route Sắp đặt và kết nối (trong quá trình hiện thực hóa FPGA PCF : Physical Constraint File Tệp quy định các ràng buộc vật lý của thiết kế trên ISE PLA : Programmable Logic Array Mảng các khối logic khả trình PLD : Programmable Logic Device Vi mạch khả trình PROM : Programmable Read-Only Bộ nhớ ROM khả trình Memory PS/2 : IBM Personal System 2 Chuẩn giao tiếp cho các ngoại vi nhƣ chuột, bàn phím trên máy tính của IBM RAM : Read Only Memory Bộ nhớ truy cập ngẫu nhiên RSA : Ronald Rivest, Adi Thuật toán mã hóa RSA Shamir & Leonard Adleman Cryption Schema RTL : Register Tranfer Level Mô tả lớp thanh ghi truyền tải SDK : Software Development Kit Tổ hợp các chƣơng trình hỗ trợ thiết kế phần mềm nhúng của Xilinx SHL16 : Shift-Register 16 bit Thanh ghi dịch 16 bit SLICEL : SLICE Logic Phần tử Logic trong FPGA SLICEM : SLICE Memory Phần tử Logic có khả năng thực hiện chức năng nhớ trong FPGA SoC : System On a Chip Hệ thống tích hợp trên một chíp đơn. SPI : Serial Peripheral Interface Chuẩn kết nối ngoại vi nối tiếp SPLD : Simple Programmable Logic 13
- Device SRAM : Static Random Access Memory RAM tĩnh SSI : Small scale integration Vi mạch tích hợp cỡ nhỏ UART : Universal Asynchronous Receiver Chuẩn truyền tin dị bộ nối tiếp Transceiver UCF : User Constraint File Tệp quy định các điều kiện ràng buộc cho thiết kế bởi ngƣời dùng. ULSI : Ultra large scale intergration VGA : Video Graphic Array Chuẩn kết nối với màn hình máy tính VHDL : Very Hi-speed Integrated Circuit Ngôn ngữ mô tả vi mạch số tích Hardware Description Language hợp VLSI : Very large scale integration Vi mạch tích hợp cỡ rất lớn WSI : Wafer scale intergration XPS : Xilinx Platform Studio Chƣơng trình phần mềm hỗ trợ xây dựng hệ nhúng trên FPGA XST : Xilinx Synthesis Technology Chƣơng trình tổng hợp thiết kế của Xilinx 14
- Chương 1 CÁC KIẾN THỨC CƠ SỞ Chƣơng mở đầu có nhiệm vụ cung cấp cho ngƣời học những kiến thức, khái niệm cơ bản về thiết kế các khối số, trong đó có những kiến thức đƣợc nhắc lại với những bổ xung phù hợp với mục đích môn học. Ngƣời học đƣợc giới thiệu qua về cách thức thiết khối làm việc với tín hiệu số đƣợc thiết kế chế tạo, phân loại các dạng vi mạch số và các tham số cơ bản cần quan tâm khi thiết kế hay làm việc với vi mạch số. Chƣơng này cũng giới thiệu qua về sự phát triển của một lớp các IC khả trình phần cứng từ PROM cho tới FPGA. Mục đích của phần này giúp cho ngƣời học có một cái nhìn tổng quan về lịch sử của thiết kế logic số trƣớc khi tập trung vào các vấn đề kiến thức chính ở các chƣơng sau là ngôn ngữ mô tả phần cứng VHDL và công nghệ FPGA. 15
- 1. Các khái niệm chung 1.1. Transitor Là linh kiện bán dẫn có khả năng làm việc nhƣ một công tắc bật tắt hoặc dùng để khuếch đại tín hiệu. Transitor là phần tử cơ bản của mọi vi mạch số tích hợp, từ các cổng logic đơn giản AND, OR, NOT đến các loại phức tạp nhƣ các mạch điều khiển ngoại vi, vi điều khiển, vi xử lý Transitor đƣợc làm từ vật liệu bán dẫn (sermiconductor), là vật liệu vừa có khả năng dẫn điện vừa có khả năng làm việc nhƣ những vật liệu cách điện, khả năng này thay đổi tùy theo kích thích từ bên ngoài nhƣ nhiệt độ, ánh sáng, trƣờng điện từ, dòng điện Chất bán dẫn dùng để cấu tạo transitor thƣờng là Germany (Ge) hoặc Silicon (Si) đƣợc kích tạp một lƣợng nhỏ Photpho(P) hoặc Boron (B) với mục đích tăng mật độ electron (kiểu N) tự do hoặc tăng mật độ lỗ trống (kiểu P) tƣơng ứng trong tinh thể bán dẫn. Cấu trúc nguyên lý của các dạng transitor đƣợc trình bày ở hình dƣới đây: Hình 1-1. Cấu trúc transitor lưỡng cực BJTS, đơn cực FETs, diode Transitor lƣỡng cực BJT (Bipolar Junction Transitor) sử dụng nhiều trong thập kỷ 80s, đặc điểm của BJT là tốc độ chuyển mạch nhanh nhƣng nhƣợc điểm là mức tiêu thụ năng lƣợng lớn ngay cả trong trạng thái nghỉ và chiếm nhiều diện tích. Sau đó BJTs dần đƣợc thay thế bằng transitor đơn cực FETs(Field Effect Transitors) làm việc trên hiệu ứng trƣờng và kênh dẫn chỉ dùng một loại bán dẫn loại p hoặc n. MOSFETs (Metal-oxide-sermiconductor Field-Effect-Transitors) là transitor FETs nhƣng dùng cực Cổng metal (về sau lớp metal đƣợc thay bằng polysilicon) phủ trên một lớp oxide cách điện và lớp này phủ trên vật liệu bán 16
- dẫn, tùy theo loại vật liệu bán dẫn mà transitor này có tên gọi là NMOS (kênh dẫn n) và PMOS (kênh dẫn p). CMOS (Complementary-Symmetry Metal-Oxide Sermiconductor) là transitor tạo thành từ việc ghép cặp bù PMOS và NMOS, có nhiều ƣu điểm so với các dòng transitor cũ nhƣ hiệu điện thế làm việc thấp, độ chống nhiễu cao, tiêu tốn ít năng lƣợng và cho phép tích hợp trong IC số với mật độ cao. CMOS là công nghệ transitor đƣợc sử dụng rộng rãi nhất hiện nay. 1.2. Vi mạch số tích hợp Còn đƣợc gọi là IC – Intergrated Circuits, chip, là cấu trúc mạch điện đƣợc thu nhỏ bằng cách tích hợp chủ yếu từ các transitor với mật độ cao, ngoài ra còn có thể có các linh kiện điện thụ động khác trên một khối bán dẫn mỏng. Các vi mạch tích hợp đều có một số lƣợng tín hiệu đầu vào và đầu ra để thực hiện một chức năng cụ thể nào đó. Trong khuôn khổ giáo trình này chủ yếu nghiên cứu về vi IC số, tức là dạng IC chỉ làm việc với các tín hiệu số. . . . . . . IC a) b) Hình 1-2: a) Mô hình Vi mạch số tích hợp b) Vi mạch tích hợp thực tế Vi mạch tích hợp ra đời từ những năm 1960s và đƣợc ứng dụng rộng rãi trong thực tế, đã và đang tạo ra cuộc cách mạng trong lĩnh vực điện tử. Ví dụ về vi mạch tích hợp nhƣ các IC đa dụng (general purposes IC) họ 7400, 4000, các dòng vi xử lý 80x86 dùng trong máy vi tính, chíp xử lý dùng cho điện thoại di động, máy ảnh kỹ thuật số, các vi điều khiển dùng trong các thiết bị dân dụng, ti vi, máy giặt, lò vi sóng Các vi mạch này có mật độ tích hợp từ hàng vài chục đến hàng trăm triệu, và hiện nay đã đến hàng tỷ transitor trong một miếng bán dẫn có kích thƣớc xấp xỉ kích thƣớc đồng xu. Mật độ tích hợp đƣợc định nghĩa là tổng số những phần tử tích cực (transitor hoặc cổng logic) chứa trên một đơn vị 17
- diện tích của khối tinh thể bán dẫn. Theo mật độ tích hợp chia ra các loại vi mạch sau: - Vi mạch cỡ nhỏ SSI (Small scale integration), có hàng chục transitor trong một vi mạch. - Vi mạch cỡ vừa MSI (Medium scale integration), có hàng trăm transitor trong một vi mạch. - Vi mạch cỡ lớn LSI (Large scale integration), có hàng ngàn đến hàng chục ngàn transitor trong một vi mạch. - Vi mạch cực lớn VLSI (Very large scale integration), có hàng vạn, hàng triệu, hàng chục triệu transitor và lớn hơn trong một vi mạch, tới thời điểm hiện nay đã xuất hiện nhƣng vi mạch có độ tích hợp đến hàng tỷ transitor. - Vi mạch siêu lớn ULSI (Ultra large scale intergration), vi mạch có độ tích hợp với mức độ hàng triệu transitor trở lên. - WSI (Wafer-scale-Intergration) là giải pháp tích hợp nhiều vi mạch chức năng trên một tấm silicon (wafer) để tăng hiệu suất cũng nhƣ giảm giá thành sản phẩm, ví dụ hệ vi xử lý nhiều nhân đƣợc tích hợp bằng WSI. - SoC (System-on-a-Chip) Khái niệm chỉ một hệ tính toán, xử lý mà tất cả các khối chức năng số và cả tƣơng tự đƣợc thiết kế để tích hợp vào trong một chip đơn. Trong khuôn khổ chƣơng trình này sẽ dành thời lƣợng chính cho việc nghiên cứu cơ bản về công nghệ, phƣơng pháp, quá trình thiết kế các vi mạch cỡ LSI, VLSI. 1.3. Cổng logic Cổng logic hay logic gate là cấu trúc mạch điện (sơ đồ khối hình ) đƣợc lắp ráp từ các linh kiện điện tử để thực hiện chức năng của các hàm logic cơ bản y = f(xn, xn-1, , x1, x0). Trong đó các tín hiệu vào xn-1, xn-2, , x1, x0 của mạch tƣơng ứng với các biến logic xn-1, xn-2, , x1, x0 của hàm . Tín hiệu ra y của mạch tƣơng ứng với hàm logic y. Với các cổng cơ bản thƣờng giá trị n ≤ 4. x0 y x1 LOGIC GATE xn Hình 1-3. Mô hình cổng logic cơ bản 18
- Giá trị của các tín hiệu vào và ra chỉ có hai mức là mức thấp (Low - L) và mức cao (High - H) tƣơng ứng với với hai giá trị 0 và 1 của các biến logic và hàm logic. Ví dụ: Một cổng NOT loại CMOS (hình 1.4) tƣơng ứng hàm NOT hai biến Q = not A. Hình 1-4. Mạch điện cổng NOT Trên sơ đồ dễ nhận thấy rằng, chỉ khi A có mức tích cực cao thì transitor trên đóng còn transitor dƣới mở, Q có mức tích cực thấp, khi A có mức tích cực thấp thì transitor trên mở và dƣới đóng nên Q có mực tích cực cao, nhƣ vậy mạch điện với sơ đồ trên thực hiên vai trò của cổng NOT. Các mạch logic đều đƣợc biểu diễn bằng các hệ hàm logic và do đó có thể phát biểu là: Mọi mạch logic đều có thể xây dựng từ các cổng logic cơ bản. Đối với các cổng logic cơ bản đó thì có hai tham số thời gian cơ bản: Hình 1.5. Tham số thời gian của cổng NOT Thời gian trễ lan truyền Tpd (Propagation delay) là thời gian tối thiểu kể từ thời điểm bắt đầu xảy ra sự thay đổi từ đầu vào X cho tới khi sự thay đổi này tạo ra ra thay đổi xác định tại đầu ra Y, hay nói một cách khác cho tới khi đầu ra Y ổn định giá trị. 19
- Tcd (Contamination delay) là khoảng thời gian kể từ thời điểm xuất hiện sự thay đổi của đầu vào X cho tới khi đầu ra Y bắt đầu xảy ra sự mất ổn định. Sau giai đoạn mất ổn định hay còn gọi là giai đoạn chuyển tiếp tín hiệu tại đầu ra sẽ thiết lập trạng thái xác định vững bền. Nhƣ vậy Tpd > Tcd và khi nhắc đến độ trễ của cổng thì là chỉ tới giá trị Tpd. 1.4. Phần tử nhớ 1.4.1. D-Latch và D flip-flop Latch và Flip-Flop là các phần tử nhớ quan trọng trong thiết kế VLSI, sơ đồ cấu tạo chi tiết và mô tả đã đƣợc trình bày kỹ trong phần Kỹ thuật số. Ở phần này chỉ nhắc lại những tính chất cơ bản nhất của các Flip-Flop và bổ xung thêm các tham số thời gian thực của các phần tử này. Bảng 1-1 D-Flip flop và D-latch D-flip flop D-latch D SET Q Clock D Q Qprev Clock D Q CLR Q Rising edge 1 1 x 0 X Qprev Rising edge 0 0 x 1 D Non-rising x Qprev D-Latch là phần tử nhớ làm việc theo mức xung, cụ thể khi tín hiệu Clock bằng 1 thì giá trị Q đầu ra bằng giá trị đầu vào, khi tín hiệu Clock = 0 thì giá trị đầu ra không đổi. Nói một cách khác D-latch làm việc nhƣ một cửa đóng mở giữa tín hiệu Q và D tƣơng ứng với mức điện áp của xung Clock. D-flip-flop là phần tử nhớ làm việc theo sƣờn xung, có hai dạng sƣờn là sƣờn lên (rising edge) khi xung thay đổi từ 0->1 và sƣờn xuống (falling edge) khi xung thay đổi từ 1->0. Khi không có yêu cầu gì đặc biệt thì Flip-flop làm việc với sƣờn xung lên thƣờng đƣợc sử dụng. Khác với D-latch giá trị đầu ra của Flip- Flop chỉ thay vào thời điểm sƣờn xung . Với cách làm việc nhƣ vậy giá trị đầu ra sẽ không thay đổi trong suốt thời gian một chu kỳ xung nhịp dù cho tín hiệu đầu vào thay đổi. D Flip-flop rất hay đƣợc dùng trong mạch có nhớ vì vậy đôi khi nói đến phần tử nhớ thƣờng ngầm hiểu là D Flip-flop. 20
- In In Out In In Out Out Clk Out Clk Clk Clk Latch Flip-Flop Hình 1-6. Đồ thị thời gian của D Flip-flop và D Latch Đối với D-flip-flop và D-latch nhớ thì có hai tham số thời gian hết sức quan trọng là Tsetup, và Thold. Đây là tham số thời gian đối với dữ liệu đầu vào cổng Din để đảm bảo việc truyền dữ liệu sang cổng ra Qout là chính xác, cụ thể đối với Flip-flop. Tsetup: là khoảng thời gian cần thiết cần giữ ổn định đầu vào trƣớc sƣờn tích cực của xung nhịp Clock Thold: Là khoảng thời gian tối thiểu cần giữ ổn định dữ liệu đầu vào sau sƣờn tích cực của xung nhịp Clock. Din Tsetup Thold CLK Tclk_q Qout Hình 1-7. Tham số thời gian của D-Flip-Flop 1.4.2 Các flip-flop khác - RS Flip-flop: Bảng 1-2 RS Flip-flop R S Qnext S SET Q 0 0 Qprev 0 1 1 R CLR Q 1 0 0 1 1 Chạy đua 21
- RS Flip-flop có đầu vào là hai tín hiệu Reset và Set. Set =1 thì tín hiệu đầu ra nhận giá trị 1 không phụ giá trị hiện tại Q, Reset =1 thì đầu ra Q = 0 không phụ thuộc giá trị hiện tại Q. Đối với RS-flipflop không đồng bộ thì giá trị Q thay đổi phụ thuộc R/S ngay tức thì, còn đối với RS flip-flop đồng bộ thì tín hiệu Q chỉ thay đổi tại thời điểm sƣờn xung Clock. Trạng thái khi R= 1, S= 1 là trạng thái cấm vì khí đó đầu ra nhận giá trị không xác định, thực chất sẽ xảy ra sự thay quá trình ―chạy đua‖ hay tự dao động giá trị Q từ 0 đến 1 và ngƣợc lại với chu kỳ bằng độ trễ chuyển mạch của flip-flop. - JK-flip-flop Bảng 1-3 JK Flip-flop J K Qnext J SET Q 0 0 Qprev 0 1 0 K CLR Q 1 0 1 1 1 NOT Qprev Theo bảng chân lý JK-flip flip hoạt động khá linh hoạt thực hiện chức năng giống nhƣ D-flip flop hoặc RS flip-flop, trạng thái khí J=0, K=1 là Reset, J=1, K=0 là Set. Tuy không có đầu vào dữ liệu D nhƣng để JK flip-flop làm việc nhƣ một D-flip flip thì tín hiệu D nối với J còn K cho nhận giá trị đối của J. - T- flip-flop Bảng 1-4 T Flip-flop T Q Qnext 0 0 0 0 1 1 1 0 1 1 1 0 Khi T bằng 1 thì giá trị Qnextbằng đảo của giá trị trƣớc Qprev khi T = 0 thì giá trị đầu ra không thay đổi 22
- 1.5 Mạch logic tổ hợp Mạch logic tổ hợp (Combinational logic circuit) là mạch mà giá trị tổ hợp tín hiệu ra tại một thời điểm chỉ phụ thuộc vào giá trị tổ hợp tín hiệu vào tại thời điểm đó. Hiểu một cách khác mạch tổ hợp không có trạng thái, không chứa các phần tử nhớ mà chỉ chứa các phần tử thực hiện logic chức năng nhƣ AND, OR, NOT Đối với mạch tổ hợp tham số thời gian trễ Tdelay là khoảng thời gian lớn nhất kể từ thời điểm xác định tất cả các giá trị đầu vào cho tới thời điểm tất cả các kết quả ở đầu ra trở nên ổn định. Trên thực tế với vi mạch tích hợp việc thời gian trễ rất nhỏ nên việc tìm tham số độ trễ của mạch đƣợc thực hiện bằng cách liệt kê tất cả các đƣờng biến đổi tín hiệu có thể từ tất cả các đầu vào tới tất cả đầu ra sau đó dựa trên thông số về thời gian của các cổng và độ trễ đƣờng truyền có thể tính đƣợc độ trễ của các đƣờng truyền này và tìm ra đƣờng truyền có độ trễ lớn nhất, giá trị đó chính là Tdelay. Hìn h 1-8. Độ trễ của mạch tổ hợp Minh họa cho độ trễ trong mạch tổ hợp nhƣ ở hình 1-8. Về lý thuyết để xác định độ trễ của mạch cần liệt kê tất cả các đƣờng tín hiệu từ 4 đầu vào In1, In2, In3, In4 đến 2 đầu ra Out1, Out2. Đối với mỗi cặp đầu ra đầu vào tồn tại nhiều đƣờng truyền khác nhau vì vậy tổng số lƣợng các đƣờng truyền này thƣờng rất lớn. Chính vì thế đối với những mạch tổ hợp lớn thì việc xác định độ trễ đều phải thực hiện bằng sự hỗ trợ của máy tính. Ví dụ để xác định độ trễ của hai đƣờng truyền 1 và 2 trên hình vẽ: đƣờng 1 lần lƣợt đi qua các cổng NOT, AND_4, NOR, AND_3, OR. Đƣờng 2 lần lƣợt đi qua cổng NOT, AND, OR_4, AND_4, OR_4. Độ trễ của các đƣờng truyền này tính bằng độ trễ của các cổng nó đi qua cộng với độ trễ dây dẫn (TWrite). 23
- T1 = TNOT + TAND_4 + TNOR + TAND_3 + T AND_3 + TWire1 (1.1) T2 = TNOT + TAND + TOR_4 + TAND_4 + T OR_4 + TWire2 (1.2) Do độ trễ của cổng nhiều đầu vào lớn hơn độ trễ của cổng ít đầu vào nên mặc dù số cổng đi qua trên đƣờng truyền nhƣ nhau nhƣng đƣờng truyền 2 sẽ có độ trễ lớn hơn đƣờng 1. Các đƣờng truyền có độ trễ lớn nhất đƣợc gọi là Critical paths. Các đƣờng truyền này cần đặc biệt quan tâm trong quá trình tối ƣu hóa độ trễ của mạch. 1.6. Mạch logic tuần tự Mạch logic dãy (Sequential logic circuits) còn đƣợc gọi là mạch logic tuần tự là mạch số mà tín hiệu ra tại một thời điểm không những phụ thuộc vào tổ hợp tín hiệu đầu vào tại thời điểm đó mà còn phụ thuộc vào tín hiệu vào tại các thời điểm trƣớc đó. Hiểu một cách khác mạch dãy ngoài các phần tử tổ hợp có chứa các phần tử nhớ và nó lƣu trữ lớn hơn một trạng thái của mạch. Tham số thời gian của mạch tuần tự đƣợc tính khác với mạch tổ hợp, sự khác biệt đó có quan hệ mật thiết với đặc điểm của tín hiệu đồng bộ Clock. Ví dụ với một mạch tuần tự điển hình dƣới đây. Mạch tạo từ hai lớp thanh ghi sử dụng Flip-flop A và B, trƣớc giữa và sau thanh ghi là ba khối logic tổ hợp Combinational logic 1, 2, 3, các tham số thời gian cụ thể nhƣ sau: Td1, Td2, Td3. Là thời gian trễ tƣơng ứng của 3 khối mạch tổ hợp 1, 2, 3. Tsa, Tsb là thời gian thiết lập (Tsetup) của hai Flipflop A, B tƣơng ứng Tclk-q. là khoảng thời gian cần thiết để dữ liệu tại đầu ra Q xác định sau thời điểm kích hoạt của sƣờn Clock D SET Q D SET Q Combinational Combinational Combinational logic1 logic2 logic3 CLR Q CLR Q Tskew Td1 Tsa Tclk-q Td2 Tsb Tclk-q Td3 Hình 1-9. Tham số thời gian của mạch tuần tự Đối với mạch đồng bộ thì sẽ là lý tƣởng nếu nhƣ điểm kích hoạt (sƣờn lên hoặc sƣờn xuống) của xung nhịp Clock tới các Flip-flop cùng một thời điểm. Tuy vậy trên thực tế bao giờ cũng tồn tại độ trễ giữa hai xung Clock đến hai Flip-flop khác nhau. Tskew là độ trễ lớn nhất của xung nhịp Clock đến hai Flip-flop khác 24
- nhau trong mạch. Thời gian chênh lệch lớn nhất giữa tín hiệu xung nhịp , thời gian trễ này sinh ra do độ trễ trên đƣờng truyền của xung Clock từ A đến B. Trên thực tế Tskew giữa hai Flip-flop liên tiếp có giá trị rất bé so với các giá trị độ trễ khác và có thể bỏ qua, nhƣng đối với những mạch cỡ lớn khi số lƣợng Flip-flop nhiều hơn và phân bố xa nhau thì giá trị Tskew có giá trị tƣơng đối lớn. Những tham số trên cho phép tính toán các đặc trƣng thời gian của mạch tuần tự đó là: - Thời gian trễ trƣớc xung nhịp Clock tại đầu vào Tinput_delay = Td1 + Tsa (1.3) - Thời gian trễ sau xung nhịp Clock tại đầu ra. Toutput_delay = Td3 + Tclk_q (1.4) - Chu kỳ tối thiểu của xung nhịp Clock, hay là khoảng thời gian tối thiểu đảm bảo cho dữ liệu trong mạch đƣợc xử lý và truyền tải giữa hai lớp thanh ghi lien tiếp mà không xảy ra sai sót. Nếu xung nhịp đầu vào có chu kỳ nhỏ hơn Tclk_min thì mạch sẽ không thể hoạt động theo thiết kế. Tclk_min = Tclk-q + Td2 + Tsb + Tskew (1.5) - Từ đó tính đƣợc xung nhịp tối đa của vi mạch là Fmax = 1/ Tclk_min = 1/( Tclk-q + Td2 + Tsb + Tskew) (1.6) 1.7 Các phương pháp thể hiện thiết kế. Có hai phƣơng pháp cơ bản đƣợc sử dụng để mô tả vi mạch số là mô tả bằng sơ đồ logic (schematic) và mô tả bằng ngôn ngữ mô tả phần cứng HDL (Hardware Description Language). Mô tả bằng sơ đồ: vi mạch đƣợc mô tả trực quan bằng cách ghép nối các phần tử logic khác nhau một cách trực tiếp giống nhƣ ví dụ ở hình vẽ dƣới đây. Thông thƣờng các phần tử không đơn thuần là các đối tƣợng đồ họa mà còn có các đặc tính vật lý gồm chức năng logic, thông số tải vào ra, thời gian trễ Những thông tin này đƣợc lƣu trữ trong thƣ viện logic thiết kế. Mạch vẽ ra có thể đƣợc mô phỏng để kiểm tra chức năng và phát hiện và sửa lỗi một cách trực tiếp. 25
- D1 U1 U14 AND-2 U2 NOR AND-2 D2 U3 U13 AND-2 NOR U12 D3 U4 NOR AND-2 U5 U11 U10 AND-2 U6 AND-2 NOR AND-2 U7 R AND-2 U8 S SET Q AND-2 U9 AND-2 U15 R CLR Q AND-2 Hình 1-10. Mô tả mạch số bằng sơ đồ Ƣu điểm của phƣơng pháp này là cho ra sơ đồ các khối logic rõ ràng thuận tiện cho việc phân tích mạch, tuy vậy phƣơng pháp này chỉ đƣợc sử dụng để thiết kế những mạch cỡ nhỏ, độ phức tạp không cao. Đối với những mạch cỡ lớn hàng trăm ngàn cổng logic thì việc mô tả đồ họa là gần nhƣ không thể và nếu có thể cũng tốn rất nhiều thời gian, chƣa kể những khó khăn trong công việc kiểm tra lỗi trên mạch sau đó. Mô tả bằng HDL: HDL cho phép mô tả vi mạch bằng các cú pháp tƣơng tự nhƣ cú pháp của ngôn ngữ lập trình. Có ba ngôn ngữ mô tả phần cứng phổ biến hiện nay là: Verilog: Ra đời năm 1983, do hai kỹ sƣ Phil Moorby và Prabhu Goel làm việc tại Automated Integrated Design Systems (sau này thuộc sở hữu của Cadence). Verilog đƣợc IEEE chính thức tiêu chuẩn hóa vào năm 1995 và sau đó là các phiên bản năm 2001, 2005. Đây là một ngôn ngữ mô tả phần cứng có cấu 26
- trúc và cú pháp gần giống với ngôn ngữ lập trình C, ngoài khả năng hỗ trợ thiết kế logic thì Verilog rất mạnh trong việc hỗ trợ cho quá trình kiểm tra thiết kế. VHDL: VHDL viết tắt của Very-high-speed intergrated circuits Hardware Description Language, hay ngôn ngữ mô tả cho các mạch tích hợp tốc độ cao. VHDL lần đầu tiên đƣợc phát triển bởi Bộ Quốc Phòng Mỹ nhằm hỗ trợ cho việc thiết kế những vi mạch tích hợp chuyên dụng (ASICs). VHDL cũng đƣợc IEEE chuẩn hóa vào các năm 1987, 1991, 2002, và 2006 và mới nhâts 2009. VHDL đƣợc phát triển dựa trên cấu trúc của ngôn ngữ lập trình Ada. Cấu trúc của mô tả VHDL tuy phức tạp hơn Verilog nhƣng mang tính logic chặt chẽ và gần với phần cứng hơn. AHDL: Altera HDL đƣợc phát triển bởi công ty bán dẫn Altera với mục đích dùng thiết kế cho các sản phẩm FPGA và CPLD của Altera. AHDL có cấu trúc hết sức chặt chẽ và là ngôn ngữ rất khó sử dụng nhất so với 2 ngôn ngữ trên. Bù lại AHDL cho phép mô tả thực thể logic chi tiết và chính xác hơn. Ngôn ngữ này ít phổ biến tuy vậy nó cũng đƣợc rất nhiều chƣơng trình phần mềm hỗ trợ mô phỏng biên dịch. Bên cạnh các ngôn ngữ trên thì một loạt các ngôn ngữ khác đã và đang phát triển cũng hỗ trợ khả năng mô tả phần cứng, đáng chú ý là System Verilog là phiên bản mở rộng của Verilog hƣớng của C++ nhƣ hỗ trợ các kiểu dữ liệu khác nhau, sử dụng Class và nhiều hàm hệ thống bậc cao. SystemC không hoàn toàn phải là một HDL mà là một dạng mở rộng của C++ cho phép hỗ trợ kiểm tra các thiết kế bằng VHDL hay Verilog. 2. Yêu cầu đối với một thiết kế logic Yêu cầu đối với một thiết kế IC bao gồm: Yêu cầu chức năng: mạch gồm có các đầu vào đầu ra nhƣ thế nào, thực hiện nhiệm vụ gì Yêu cầu về mặt công nghệ: Mạch thiết kế sử dụng nền công nghệ bán dẫn nào PLD, ASIC, FPGA Yêu cầu về mặt tài nguyên: Giới hạn về số lƣợng cổng, số lƣợng transitors, về diện tích quy đổi chuẩn, về kích thƣớc của IC thiết kế. Yêu cầu về khả năng làm việc (performance): là yêu cầu về các tham số thời gian của mạch bao gồm độ trễ cổng vào, độ trễ cổng ra, độ trễ logic với mạch tổ hợp, các xung nhịp làm việc, số lƣợng xung nhịp cho một chu trình xử lý dữ liệu, số lƣợng dữ liệu xử lý trên một đơn vị thời gian. 27
- Yêu cầu về mức tiêu hao năng lƣợng (power consumtion). Yêu cầu về chi phí cho quá trình thiết kế và chế tạo (design cost). Các yêu cầu kể trên có quan hệ mật thiết với nhau và thông thƣờng chúng không thể đồng thời đạt đƣợc tối ƣu. Ví dụ năng lƣợng tiêu thụ của mạch muốn nhỏ thì số lƣợng cổng sử dụng hạn chế và sẽ hạn chế tốc độ làm việc, hoặc việc sử dụng các công nghệ rẻ tiền hơn hoặc dùng các cổng công xuất thấp cũng là nhân tố giảm hiệu năng làm việc của mạch. Trong thực tế Các IC phục vụ các mục đích khác nhau thì có yêu cầu khác nhau và ngƣời lập kế hoạch thiết kế chế tạo IC cần phải cân đối giữa các tiêu chí để có một phƣơng án tối ƣu nhất. Ví dụ cùng là vi xử lý nhƣng nếu dùng thì không có yêu cầu đặc biệt về mặt tiêu hao năng lƣợng do nguồn cấp là cố định, khi đó Chip phải đƣợc thiết kế để có hiệu suất làm việc tối đa. Trong khi vi xử lý cho máy tính xách tay thì cần phải thiết kế để có mức tiêu thụ năng lƣợng thấp nhất có thể hoặc để có thể hoạt động ở nhiều mức tiêu thụ năng lƣợng khác nhau nhằm kéo dài thời gian sử dụng. Chip điều khiển cho các thiết bị di động thì cần phải tối ƣu hết mức mức tiêu tốn năng lƣợng bằng cách thu gọn thiết kế, giảm thiểu những tập lệnh không cần thiết và sử dụng các phần tử tiết kiệm năng lƣợng nhất 3. Các công nghệ thiết kế mạch logic số Vi mạch số đơn giản có thể đƣợc thiết kế thủ công (Manual IC design), nhƣng với các vi mạch số cỡ lớn thì quá trình thiết kế buộc phải sử dụng các chƣơng trình hỗ trợ thiết kế trên máy tính (Design Automation) Manual design: Vi mạch số có thể đƣợc thiết kế bởi cách ghép nối các linh kiện bán dẫn rời rạc. Sự ra đời các IC đa dụng họ 74XX hay 40XX cho phép ngƣời sử dụng có thể tự thiết kế những mạch số cỡ nhỏ và cỡ vừa bằng cách ghép nối trên một bản mạch in. Nhờ có cấu trúc chuẩn hóa, có thể dễ dàng ghép nối, tạo những mạch chức năng khác nhau. Trên thực tế những mạch dạng này đã và vẫn đang đƣợc ứng dụng rộng rãi. Điểm hạn chế duy nhất của những thiết kế dạng này là chúng chỉ phù hợp cho những thiết kế SSI đơn giản do giới hạn về mật độ tích hợp và tốc độ làm việc thấp. 28
- IC Design Manual Design Design Automation 7400 Series 4000 Series Discrete Programable Full-custom Semi-custom (TTL) (CMOS) components Device Based ASIC ASIC Field PD SPLD CPLD (FPGA) PROM (EPROM, PLA PAL GAL E2PROM) Hình 1-11. Phân loại thiết kế vi mạch số Design Automation Máy tính là một sản phẩm đặc trƣng nhất của nền công nghiệp sản xuất chế tạo bán dẫn nhƣng ngay sau khi ra đời đã trở thành công cụ đắc lực cho việc thiết kế mô phỏng IC nói riêng và các thiết bị khác nói chung. Tự động hóa thiết kế không những giúp đơn giản hóa và rút ngắn đáng kể thời gian thiết kế sản phẩm mà còn đem lại những khả năng mà quá trình thiết kế thủ công bởi con ngƣời không làm đƣợc đó là: Khả năng làm việc với những thiết kế phức tạp tới cỡ hàng nghìn đến hàng tỷ transitor. Khả năng xử lý những bài toán tối ƣu với nhiều tiêu chí và nhiều điều kiện ràng buộc phức tạp. Khả năng tự động tổng hợp thiết kế từ các mức trừu tƣợng cao xuống các mức trừu tƣợng thấp hơn một cách chính xác, nhanh chóng. Đơn giản hóa việc lƣu trữ và trao đổi dữ liệu thiết kế. Các phần mềm hỗ trợ thiết kế gọi chung là CAD Tools, trong lĩnh vực thiết kế ASIC có 3 hệ thống phần mềm phổ biến của Cadence®, Synopsys®, Magma® Design Automation Inc. Trong thiết kế trên FPGA phổ biến có Xilinx, Altera. 29
- Trong tự động hóa thiết kế IC thƣờng phân biệt thành những quy trình nhƣ sau: Full-custom ASIC: là quy trình thiết kế IC có mức độ chi tiết cao nhất nhằm thu đƣợc sản phẩm có hiệu quả làm việc cao nhất trong khi vẫn đạt tối ƣu về mặt tài nguyên trên nền một công nghệ bán dẫn nhất định. Để đạt đƣợc mục đích đó thiết kế không những đƣợc tối ƣu ở những mức cao mà còn đƣợc tối ƣu ở mức độ bố trí transitor và kết nối giữa chúng, ví dụng hai khối logic cùng thực hiện hàm OR nhƣng phân bố ở hai vị trí khác nhau thì đƣợc cấu trúc bằng các mạch transitor khác nhau, phụ thuộc vào các thông số khác nhƣ tải đầu vào đầu ra, vị trí, ảnh hƣởng các khối liền kề Chính vì thế Full-custom ASIC đôi khi còn đƣợc gọi là random-logic gate networks nghĩa là mạch tạo bởi những cổng không đồng nhất. Semi-custom ASIC design: Phân biệt với Full-custom ASIC design, khái niệm này chỉ quy trình thiết kế mà mức độ chi tiết không đạt đến tối đa, thông thƣờng thiết kế đạt chi tiết đến mức cổng logic hoặc cao hơn. Do Full-custom ASIC có độ phức tạp cao nên không những chi phí cho quá trình thiết kế rất lớn mặt khác thời gian dành cho thiết kế có thể kéo dài hàng vài năm trở lên, trong thời gian đó có thể đã có những công nghệ mới ra đời, mỗi một thay đổi nhỏ kéo theo việc phải làm lại gần nhƣ toàn bộ thiết kế và phát sinh thêm chi phí rất nhiều do vậy lợi nhuận sản phẩm bán ra thấp hay thậm chí thua lỗ. Semi-custom ASIC cân bằng giữa chi phí thiết kế và lợi nhuận thu đƣợc sản phẩm bằng cách đẩy nhanh và giảm thiểu chi phí cho quá trình thiết kế, dĩ nhiên bù lại sản phẩm làm ra không đạt đƣợc mức tối ƣu lý thuyết nhƣ Full-custom design. Có nhiều dạng Semi-custom design nhƣng một trong những kiểu cơ bản mà thƣờng đƣợc sử dụng là thiết kế trên cơ sở thƣ viện cổng chuẩn (Standard Cell Library), thƣ viện này là tập hợp của các cổng logic nhƣ AND, OR, XOR, thanh ghi và vì chúng có cùng kích thƣớc chiều cao nên đƣợc gọi là cổng chuẩn. ASIC based on Programmable Device: Thiết kế ASIC trên cơ sở IC khả trình. Chíp khả trình (Programmable device) đƣợc hiểu là IC chứa những phần tử logic có thể đƣợc lập trình can thiệp để tái cấu trúc nhằm thực hiện một chức năng nào đó. Quá trình tái cấu trúc thực hiện thông qua ngôn ngữ mô tả phần cứng nên thƣờng đƣợc gọi ngắn gọn là lập trình. IC khả trình đƣợc chia thành các dạng sau: SPLD (Simple Programmable Logic Device) Nhóm những IC khả trình PROM, PAL, PLA, GAL. Đặc điểm chung của nhóm này là chứa một số lƣợng 30
- cổng tƣơng đƣơng từ vài chục (PROM) đến vài trăm (PAL, GAL) cổng, nhóm này sử dụng cấu trúc của bộ nhớ ROM để lƣu cấu hình IC, (vì vậy nhóm này còn gọi là Memory-based PLD), cấu trúc này bao gồm một mảng ma trận AND và một mảng ma trận OR có thể cấu trúc đƣợc. Trong các chip dạng này lại chia làm hai, thứ nhất là loại chỉ lập trình một lần, và loại có khả năng tái lập trình dùng các công nghệ nhƣ EEPROM hay EPROM. Cấu trúc cụ thể và nguyên lý làm việc của PROM, PAL, PLA, GAL, FPGA, CPLD sẽ đƣợc lần lƣợt đƣợc trình bày chi tiết ở phần tiếp theo. CPLD (Complex Programmable Logic Device) CPLD là IC lập trình phức tạp thƣờng đƣợc ghép từ nhiều các SPLD trên một chip đơn. Số cổng tƣơng đƣơng của CPLD đạt từ hàng nghìn đến hàng chục nghìn cổng. FPGA (Field-Programmable Gate Array) là IC khả trình cấu trúc từ mảng các khối logic lập trình đƣợc. Nếu nhƣ đối với các PLD khác việc tái cấu trúc IC đƣợc thực hiện trong điều kiện của nhà máy sản xuất bán dẫn, quá trình này cần những mặt nạ cho quang khắc nên sử dụng lớp những PLD này đƣợc gọi chung bằng thuật ngữ Mask-Programmable Device. FPGA phân biệt chính với các loại trên ở khả năng tái cấu trúc IC bởi ngƣời dùng cuối hay chính là ngƣời lập trình IC. 4. Kiến trúc của các IC khả trình Trong Kỹ thuật số ta đã chỉ ra mọi hàm logic tổ hợp đều có thể biểu diển dƣới dạng chuẩn tắc tuyển tức là dƣới dạng tổng của các tích đầy đủ, hoặc chuẩn tắc hội, tức là dạng tích của các tổng đầy đủ. Hai cách biểu diễn này là hoàn toàn tƣơng đƣơng. Nguyên lý này cho phép hiện thực hóa hệ hàm logic tổ hợp bằng cách ghép hai mảng ma trận nhân (AND) và ma trận cộng (OR). Nếu một trong các mảng này có tính khả trình thì IC sẽ có tính khả trình. Ta sẽ lần lƣợt nghiên cứu cấu trúc của một số loại IC hoạt động trên nguyên lý này. 4.1. Kiến trúc PROM, PAL, PLA, GAL 4.1.1. PROM PROM (Programmable Read-Only Memory) đƣợc phát minh bởi Wen Tsing Chow năm 1956 khi làm việc tại Arma Division của công ty American Bosch Arma tại Garden, New York. PROM đƣợc chế tạo theo đơn đặt hàng từ lực lƣợng không quân của Mỹ lúc bấy giờ với mục đích có đƣợc một thiết bị lƣu 31
- trữ các tham số về mục tiêu một các an toàn và linh động. Thiết bị này dùng trong máy tính của hệ thống phóng tên lửa Atlas E/F và đƣợc giữ bí mật trong vòng vài năm trƣớc khi Atlas E/F trở nên phổ biến. PROM là vi mạch lập trình đầu tiên và đơn giản nhất trong nhóm các vi mạch bán dẫn lập trình đƣợc (Programmable Logic Device). PROM có số đầu vào hạn chế, thông thƣờng đến 16 đến 32 đầu vào, vì vậy chỉ thực hiện đƣợc những hàm đơn giản. Cấu trúc của PROM tạo bởi ma trận tạo bởi mảng cố định các phần tử AND nối với mảng các phần tử OR lập trình đƣợc. a b c Mảng OR lập trình được T1 x x x T2 x x T3 x T4 x x T5 x x T6 x x T7 x x T8 x x Mảng AND cố định x y z w Hình 1-12. Cấu trúc PROM Tại mảng nhân AND, các đầu vào sẽ đƣợc tách thành hai pha, ví dụ a thành pha thuận a và nghịch , các chấm (•) trong mảng liên kết thể hiện kết nối cứng, tất cả các kết nối trên mỗi đƣờng ngang sau đó đƣợc thực hiện phép logic AND, nhƣ vậy đầu ra của mỗi phần tử AND là một nhân tử tƣơng ứng của các đầu vào. Ví dụ nhƣ hình trên thu đƣợc các nhân tử T1,T3 nhƣ sau: 32
- Các nhân tử đƣợc gửi tiếp đến mảng cộng OR, ở mảng này ―X‖ dùng để biểu diễn kết nối lập trình đƣợc. Ở trạng thái chƣa lập trình thì tất cả các điểm nối đều là X tức là không kết nối, tƣơng tự nhƣ trên, phép OR thực hiện đối với toàn bộ các kết nối trên đƣờng đứng và gửi ra các đầu ra X, Y, Z, Tƣơng ứng với mỗi đầu ra nhƣ vậy thu đƣợc hàm dƣới dạng tổng của các nhân tử, ví dụ tƣơng ứng với đầu ra Y: + (1.6) Tính khả trình của PROM đƣợc thực hiện thông qua các kết nối antifuse (cầu chì ngƣợc). Antifuse là một dạng vật liệu làm việc với cơ chế nhƣ vật liệu ở cầu chì (fuse) nhƣng theo chiều ngƣợc lại. Nếu nhƣ cầu chì trong điều kiện kích thích (quá tải về dòng điện) thì nóng chảy và ngắt dòng thì antifuse trong điều kiện tƣơng tự nhƣ tác động hiệu thế phù hợp sẽ biến đổi từ vật liệu không dẫn điện thành dẫn điện. Ở trạng thái chƣa lập trình thì các điểm nối là antifuse nghĩa là ngắt kết nối, khi lập trình thì chỉ những điểm nối xác định bị ―đốt‖ để tạo kết nối vĩnh viễn. Quá trình này chỉ đƣợc thực hiện một lần và theo một chiều vì PROM không thể tái lập trình đƣợc. Những IC dạng PROM có khả năng tái lập trình là UEPROM (Ultraviolet- Eraseable PROM) sử dụng tia cực tím và EEPROM (Electric-Eraseable PROM) sử dụng hiệu điện thế ngƣỡng cao để thiết lập lại các kết nối trong ma trận lập trình. 4.1.2. PAL PAL(Programmable Array Logic) ra đời cuối những năm 1970s. Cấu trúc của PAL kế thừa cấu trúc của PROM, sử dụng hai mảng logic nhƣng nếu nhƣ ở PROM mảng OR là mảng lập trình đƣợc thì ở PAL mảng AND lập trình đƣợc còn mảng OR đƣợc gắn cứng, nghĩa là các thành phần tích có thể thay đổi nhƣng tổ hợp của chúng sẽ cố định, cải tiến này tạo sự linh hoạt hơn trong việc thực hiện các hàm khác nhau. Ngoài ra cấu trúc cổng ra của PAL còn phân biệt với PROM ở mỗi đầu ra của mảng OR lập trình đƣợc đƣợc dẫn bởi khối logic gọi là Macrocell. Hình dƣới đây minh họa cho cấu trúc của macrocell. Mỗi macrocell chứa 1 Flip-Flop Register, hai bộ dồn kênh (Multiplexers) 2 và 4 đầu vào Mux2, Mux4. Đầu ra của Mux2 thông qua một cổng 3 trạng thái trả lại mảng AND, thiết kế này cho 33
- kết quả đầu ra có thể sử dụng nhƣ một tham số đầu vào, tất nhiên trong trƣờng hợp đó thì kết quả đầu ra buộc phải đi qua Flip-flop trƣớc. a b c Mảng OR cố định x x x T1 x x x x T2 x x x x T3 x x x x T4 x x x x T5 x x Mảng AND lập trình được macxrocell macyrocell macrzocell w macrocell Hình 1-13. Cấu trúc PAL Đầu ra của macrocell cũng thông qua cổng 3 trạng thái có thể lập trình đƣợc để nối với cổng giao tiếp của PAL. Tín hiệu điều khiển của Mux4 có thể đƣợc lập trình để cho phép dẫn tín hiệu lần lƣợt qua các đầu vào 0,1,2,3 của Mux4 và gửi ra ngoài cổng giao tiếp IO, tùy thuộc vào cấu hình này mà tín hiệu tại IO có thể bị chặn (không gửi ra), dẫn trực tiếp từ mảng OR, thông qua thanh ghi Register. Nhờ cấu trúc macrocell PAL có thể đƣợc sử dụng không những để thực hiện các hàm logic tổ hợp mà cả các hàm logic tuần tự. 2 SET 3 D Q Mux4 0 IO ENB CLR Q 1 S0 S1 programmable ENB 0 Mux2 1 Hình 1-14. Cấu trúc Macrocell 34
- 4.1.3. PLA PLA (Programable Logic Array) ra đời năm 1975 và là chíp lập trình thứ hai sau PROM. Cấu trúc của PLA không khác nhiều so với cấu trúc của PAL, ngoại trừ khả năng lập trình ở cả hai ma trận AND và OR. Nhờ cấu trúc đó PLA có khả năng lập trình linh động hơn, bù lại tốc độ của PLA thấp hơn nhiều so với PROM và PAL và các sản phẩm cùng loại khác. Thực tế PLA đƣợc ứng dụng không nhiều và nhanh chóng bị thay thế bởi những công nghệ mới hơn nhƣ PAL, GAL, CPLD a b c Mảng OR lập trình được x x x T1 x x x x x x T2 x x x x T3 x x x x T4 x x x x T5 x x Mảng AND lập trình được macrocell macrocell macrocell macrocell x y z w Hình 1-15. Cấu trúc PLA 4.1.4. GAL GAL (Generic Array Logic) đƣợc phát triển bởi Lattice Semiconductor company vào năm 1983, cấu trúc của GAL không khác biệt PAL nhƣng thay vì lập trình sử dụng công nghệ antifuse thì ở GAL dùng CMOS electrically erasable PROM, chính vì vậy đôi khi tên gọi GAL ít đƣợc sử dụng thay vì đó GAL đƣợc hiểu nhƣ một dạng PAL đƣợc cải tiến. 35
- 4.2. Kiến trúc CPLD, FPGA 4.2.1. CPLD Tất cả các chip khả trình PROM, PAL, GAL, thuộc nhóm SPLD (Simple Programmable Logic Devices) những IC này có ƣu điểm là thiết kế đơn giản, chi phí thấp cho sản xuất cũng nhƣ thiết kế, có thể chuyển dễ dàng từ công nghệ này sang công nghệ khác tuy vậy nhƣợc điểm là tốc độ làm việc thấp, số cổng logic tƣơng đƣơng nhỏ do đó không đáp ứng đƣợc những thiết kế phức tạp đòi hỏi nhiều về tài nguyên và tốc độ. CPLD (Complex Programmable Logic Devices) đƣợc Altera tiên phong nghiên cứu chế tạo đầu tiên nhằm tạo ra những IC khả trình dung lƣợng lớn MAX5000, MAX7000, MAX9000 là họ những CPLD tiêu biểu của hãng này. Sau sự thành công của Altera một loạt các hãng khác cũng bắt tay vào nghiên cứu chế tạo CPLD, Xilinx với các sản phẩm XC95xx series, Lattice với isp Mach 4000 serise, ispMarch XO Logic block Logic block Logic block Logic block Programmable Interconnect matrix Logic block Logic block Logic block Logic block Hình 1-16. Cấu trúc CPLD Một cách đơn giản nhất có thể hiểu CPLD đƣợc cấu trúc bằng cách ghép nhiều các chíp SPLD lại, thông thƣờng là PAL. Tuy vậy về bản chất độ phức tạp của CPLD vƣợt xa so với các IC nhóm SPLD và cấu trúc của các CPLD cũng rất 36
- đa dạng, phụ thuộc vào từng hãng sản xuất cụ thể. Dƣới đây sẽ trình bày nguyên lý chung nhất của các chip họ này. CPLD đƣợc tạo từ hai thành thành phần cơ bản là nhóm các khối logic (Logic block) và một ma trận kết nối khả trình PIM (Programmable Interconnect Matrix). Logic block là các SPLD đƣợc cải tiến thƣờng chứa từ 8 đên 16 macrocells. Tất cả các Logic block giống nhau về mặt cấu trúc. PIM là ma trận chứa các kết nối khả trình, nhiệm vụ của ma trận này là thực hiện kết nối giữa các LB và các cổng vào ra IO của CPLD. Về mặt lý thuyết thì ma trận này có thể thực hiện kết nối giữa hai điểm bất kỳ. CPLD thông thƣờng sử dụng các công nghệ lập trình của EEPROM, điểm khác biệt là đối với CPLD thƣờng không thể dùng những programmer đơn giản cho PAL, PLA vì số chân giao tiếp của CPLD rất lớn. Để thực hiện cấu hình cho CPLD mỗi một công ty phát triển riêng cho mình một bộ công cụ và giao thức, thông thƣờng các chip này đƣợc gắn trên một bo mạch in và dữ liệu thiết kế đƣợc tải vào từ máy vi tính. Tuy vậy các quy trình nạp trên đang dần bị thay thế bởi giao thức chuẩn JTAG (Join Test Action Group) chuẩn, đây cũng là giao thức dùng để cấu trúc cho FPGA mà ta sẽ nghiên cứu kỹ hơn ở chƣơng kế tiếp. Nhờ kế thừa cấu trúc của SPLD nên CPLD không cần sử dụng bộ nhớ ROM ngoài để lƣu cấu hình của IC, đây là một đặc điểm cơ bản nhất phân biệt CPLD với các IC khả trình cỡ lớn khác nhƣ FPGA. 4.2.2. FPGA Về cấu trúc chi tiết và cơ chế làm việc của FPGA sẽ đƣợc dành riêng giới thiệu trong chƣơng sau. Ở đây chỉ giới thiệu kiến trúc tổng quan nhất của IC dạng này. FPGA đƣợc cấu thành từ các khối logic (Logic Block) đƣợc bố trí dƣới dạng ma trận, chúng đƣợc nối với nhau thông qua hệ thống các kênh kết nối lập trình đƣợc Hệ thống này còn có nhiệm vụ kết nối với các cổng giao tiếp IO_PAD của FPGA. 37
- IO_PAD IO_PAD IO_PAD I O _ I P O A LOGIC BLOCK LOGIC BLOCK _ D LOGIC BLOCK P A D I O I _ O P LOGIC BLOCK LOGIC BLOCK LOGIC BLOCK _ A P D A D IP_COREs, RAM, Interconnect ROM wires . . I I O O _ _ P P A LOGIC BLOCK LOGIC BLOCK A D LOGIC BLOCK D IO_PAD IO_PAD IO_PAD Hình 1-17. Kiến trúc tổng quan của FPGA FPGA là công nghệ IC lập trình mới nhất và tiên tiến nhất hiện nay. Thuật ngữ Field-Programmable chỉ quá trình tái cấu trúc IC có thể đƣợc thực hiện bởi ngƣời dùng cuối, trong điều kiện bình thƣờng. Ngoài khả năng đó FPGA có mật độ tích hợp logic lớn nhất trong số các IC khả trình với số cổng tƣơng đƣơng lên tới hàng trăm nghìn, hàng triệu cổng. FPGA không dùng các mảng lập trình giống nhƣ trong cấu trúc của PAL, PLA mà dùng ma trận các khối logic. Điểm khác biệt cơ bản thứ ba của FPGA so với các IC kể trên là ở cơ chế tái cấu trúc, toàn bộ cấu hình của FPGA thƣờng đƣợc lƣu trong một bộ nhớ động (RAM), chính vì thế mà khi ứng dụng FPGA thƣờng phải kèm theo một ROM ngoại vi để nạp cấu hình cho FPGA mỗi lần làm việc. Kiến trúc và cách thức làm việc của FPGA sẽ đƣợc nghiên cứu cụ thể ở chƣơng thứ 3 của giáo trình này. 38
- Câu hỏi ôn tập chương 1 1. Transitor khái niệm, phân loại. 2. Khái niệm, phân loại vi mạch số tích hợp. 3. Cổng logic cơ bản, tham số thời gian của cổng logic tổ hợp. 4. Các loại Flip-flop cơ bản, tham số thời gian của Flip-flop. 5. Khái niệm mạch logic tổ hợp, cách xác định độ trễ trên mạch tổ hợp, khái niệm critical paths. 6. Khái niệm mạch dãy, cách tính thời gian trễ trên mạch dãy, khái niệm RTL, phƣơng pháp tăng hiệu suất mạch dãy. 7. Các yêu cầu chung đối với thiết kế mạch logic số. 8. Các phƣơng pháp thể hiện thiết kế mạch logic số. 9. Các công nghệ thiết kế mạch logic số, khái niệm, phân loại. 10. Trình bày sơ lƣợc về các công nghệ thiết kế IC số trên chip khả trình. 11. Nguyên lý hiện thực hóa các hàm logic trên các IC khả trình dạng PROM, PAL, PLA, GAL. 12. Khái niệm thiết kế ASIC, các dạng thiết kế ASIC. 13. Khái niệm FPGA, đặc điểm FPGA. 39
- Chương 2 NGÔN NGỮ MÔ TẢ PHẦN CỨNG VHDL Chƣơng 2 tập trung vào giới thiệu về ngôn ngữ mô tả phần cứng VHDL, đây là một ngôn ngữ mô tả phần cứng có tính ứng dụng cao nhƣng cũng có cú pháp không quen thuộc và dễ tiếp cận. Nội dung kiến thức trình bày trong chƣơng này theo định hƣớng nhƣ một tài liệu tra cứu hơn là bài giảng. Ngƣời học không nhất thiết phải theo đúng trình tự kiến thức trình bày mà có thể tham khảo tất cả các mục một cách độc lập, bên cạnh đó là tra cứu bằng các tài liệu khác cũng nhƣ tài liệu gốc bằng tiếng Anh. Các ví dụ có trong giáo trình đều cố gắng trình bày là các ví dụ đầy đủ có thể biên dịch và mô phỏng đƣợc ngay vì vậy khuyến khích ngƣời học tích cực thực hành song song với nghiên cứu lý thuyết. Kết thúc nội dung của chƣơng này yêu cầu ngƣời học phải có kỹ năng sử dụng VHDL ở cấp độ cơ bản, có khả năng thiết kế các khối số vừa và nhỏ nhƣ Flip-flop, khối chọn kênh, phân kênh, khối cộng, dịch, các khối giải mã đã biết trong chƣơng trình Điện tử số, đó cũng là các khối nền tảng cho các thiết kế lớn hơn và phức tạp hơn ở chƣơng tiếp theo. 41
- 1. Giới thiệu về VHDL VHDL viết tắt của VHSIC HDL (Very-high-speed-intergrated-circuit Hardware Description Language) hay ngôn ngữ mô tả phần cứng cho các vi số mạch tích hợp tốc độ cao. Lịch sử phát triển của VHDL trải qua các mốc chính nhƣ sau: 1981: Phát triển bởi Bộ Quốc phòng Mỹ nhằm tạo ra một công cụ thiết kế phần cứng tiện dụng có khả năng độc lập với công nghệ và giảm thiểu thời gian cũng nhƣ chi phí cho thiết kế 1983-1985: Đƣợc phát triển thành một ngôn ngữ chính thống bởi 3 công ty Intermetrics, IBM and TI. 1986: Chuyển giao toàn bộ bản quyền cho Viện Kỹ thuật Điện và Điện tử (IEEE). 1987: Công bố thành một chuẩn ngôn ngữ IEEE-1076 1987. 1994: Công bố chuẩn VHDL IEEE-1076 1993. 2000: Công bố chuẩn VHDL IEEE-1076 2000. 2002: Công bố chuẩn VHDL IEEE-1076 2002 2007: công bố chuẩn ngôn ngữ Giao diện ứng dụng theo thủ tục VHDL IEEE-1076c 2007 2009: Công bố chuẩn VHDL IEEE-1076 2009 VHDL ra đời trên yêu cầu của bài toán thiết kế phần cứng lúc bấy giờ, nhờ sử dụng ngôn ngữ này mà thời gian thiết kế của sản phẩm bán dẫn giảm đi đáng kể, đồng thời với giảm thiểu chi phí cho quá trình này do đặc tính độc lập với công nghệ, với các công cụ mô phỏng và khả năng tái sử dụng các khối đơn lẻ. Các ƣu điểm chính của VHDL có thể liệt kê ra là: Tính công cộng: VHDL là ngôn ngữ đƣợc chuẩn hóa chính thức của IEEE do đó đƣợc sự hỗ trợ của nhiều nhà sản 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, hầu nhƣ tất cả các công cụ thiết kế của các hãng phần mềm lớn nhỏ đều hỗ trợ biên dịch VHDL. Được hỗ trợ bởi nhiều công nghệ: VHDL có thể sử dụng mô tả nhiều loại vi mạch khác nhau trên những công nghệ khác nhau từ các thƣ viện rời rạc, CPLD, FPGA, tới thƣ viện cổng chuẩn cho thiết kế ASIC. Tính độ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 chức năng dùng VHDL thiết kế ở mức thanh ghi truyền tải RTL có thể đƣợc tổng hợp thành các mạch trên các công nghệ bán dẫn khác nhau. Nói một cách khác khi một công nghệ phần cứng mới ra đời nó 42
- có thể đƣợc áp dụng ngay cho các hệ thống đã thiết kế bằng cách tổng hợp các thiết kế đó lại trên thƣ viện phần cứng mới. 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 thanh ghi truyền tải (RTL–Register Tranfer Level) cho đến mức cổng (Netlist). Hiểu một cách khác VHDL có một cấu trúc mô tả phần cứng chặt chẽ có thể sử dụng ở lớp mô tả chức năng cũng nhƣ mô tả cổng trên một thƣ viện công nghệ cụ thể nào đó. Khả năng trao đổi, tái sử dụng: Việc VHDL đƣợc chuẩn hóa giúp cho việc trao đổi các thiết kế giữa các nhà thiết kế độc lập trở nên hết sức dễ dàng. Bản thiết kế VHDL đƣợc mô phỏng và kiểm tra có thể đƣợc tái sử dụng trong các thiết kế khác mà không phải lặp lại các quá trình trên. Giống nhƣ phần mềm thì các mô tả HDL cũng có một cộng đồng mã nguồn mở cung cấp, trao đổi miễn phí các thiết kế chuẩn có thể ứng dụng ở nhiều hệ thống khác nhau. 2. Cấu trúc của chương trình mô tả bằng VHDL Cấu trúc tổng thể của một khối thiết kế VHDL gồm ba phần, phần khai báo thƣ viện, phần mô tả thực thể và phần mô tả kiến trúc. Khai báo thư viện LIBRARY declaration Mô tả thực thể ENTITY Declaration Mô tả kiến trúc ARCHITECTURE Hành vi Luồng dữ liệu Cấu trúc Behavioral DataFlow Structure Hình 2-1. Cấu trúc của một thiết kế VHDL 43
- 2.1. Khai báo thư viện Khai báo thƣ viện phải đƣợc đặt đầu tiên trong mỗi thiết kế VHDL, lƣu ý rằng nếu ta sử dụng một tệp mã nguồn để chứa nhiều khối thiết kế khác nhau thì mỗi một khối đều phải yêu cầu có khai báo thƣ viện đầu tiên, nếu không khi biên dịch sẽ phát sinh ra lỗi. Ví dụ về khai báo thƣ viện library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; Khai báo thƣ viện bắt đầu bằng từ khóa Library Tên thƣ viện (chú ý là VHDL không phân biệt chữ hoa chữ thƣờng). Sau đó trên từng dòng kế tiếp sẽ khai báo các gói thƣ viện con mà thiết kế sẽ sử dụng, mỗi dòng phải kết thúc bằng dấu ―;‖. Tƣơng tự nhƣ đối với các ngôn ngữ lập trình khác, ngƣời thiết kế có thể khai báo sử dụng các thƣ viện chuẩn hoặc thƣ viện ngƣời dùng.Thƣ viện IEEE gồm nhiều gói thƣ viện con khác nhau trong đó đáng chú ý có các thƣ viện sau: - Gói IEEE.STD_LOGIC_1164 cung cấp các kiểu dữ liệu std_ulogic, std_logic, std_ulogic_vector, std_logic_vector, các hàm logic and, or, not, nor, xor các hàm chuyển đổi giữa các kiểu dữ liệu trên. std_logic, std_ulogic hỗ trợ kiểu logic với 9 mức giá trị logic (xem 4.2) - Gói IEEE.STD_LOGIC_ARITH định nghĩa các kiểu dữ liệu số nguyên SIGNED, UNSIGNED, INTEGER, SMALL INT cung cấp các hàm số học bao gồm ―+‖, ―-‖, ―*‖, ―/‖, so sánh ― ‖, ― =‖, các hàm dịch trái, dịch phải, các hàm chuyển đổi từ kiểu vector sang các kiểu số nguyên. - Gói IEEE.STD_LOGIC_UNSIGNED Cung cấp các hàm số học logic làm việc với các kiểu dữ liệu std_logic, integer và trả về giá trị dạng std_logic với giá trị không có dấu - Gói IEEE.STD_LOGIC_SIGNED Cung cấp các hàm số học logic làm việc với các kiểu dữ liệu std_logic, integer và trả về giá trị dạng std_logic với giá trị có dấu - Gói IEEE.NUMERIC_BIT Cung cấp các hàm số học logic làm việc với các kiểu dữ liệu signed, unsigned đƣợc là chuỗi của các BIT. - Gói IEEE.NUMERIC_BIT Cung cấp các hàm số học logic làm việc với các kiểu dữ liệu signed, unsigned đƣợc là chuỗi của các STD_LOGIC. 44
- - Gói IEEE.STD_LOGIC_TEXTIO chứa các hàm, thủ tục vào ra READ/WRITE để đọc ghi dữ liệu cho các định dạng STD_LOGIC, STD_ULOGIC từ FILE, STD_INPUT, STD_OUTPUT, LINE. - Gói STD.TEXTIO chứa các hàm vào ra READ/WRITE để đọc ghi dữ liệu với các định dạng khác nhau gồm, BIT, INTEGER, TIME, REAL, CHARATER, STRING từ FILE, STD_INPUT, STD_OUTPUT, LINE. - Gói IEEE.MATH_REAL, IEEE.MATH_COMPLEX cung cấp các hàm làm việc với số thực và số phức nhƣ SIN, COS, SQRT hàm làm tròn, CIEL, FLOOR, hàm tạo số ngẫu nhiên SRAND, UNIFORM và nhiều các hàm tính toán số thực khác. - Gói STD.ENV cung cấp các hàm, thủ tục hệ thống phục vụ mô phỏng gồm stop – dừng mô phỏng, finish – thoát chƣơng trình, resolution_limit trả về bƣớc thời gian mô phỏng. Cụ thể và chi tiết hơn về các thƣ viện chuẩn của IEEE có thể tham khảo thêm trong tài liệu của IEEE (VHDL Standard Language reference), và xem thêm phần Phụ lục 1 cuối sách liệt kê và phân loại đầy đủ các hàm của các thƣ viện chuẩn. 2.2. Mô tả thực thể Khai báo thực thể (entity) là khai báo về mặt cấu trúc các cổng vào ra (port), các tham số tĩnh dùng chung (generic) của một khối thiết kế VHDL. entity identifier is generic (generic_variable_declarations); port (input_and_output_variable_declarations); end entity identifier ; Trong đó - identifier là tên của khối thiết kế. - khai báo generic là khai báo các tham số tĩnh của thực thể, khai báo này rất hay sử dụng cho những thiết kế có những tham số thay đổi nhƣ độ rộng kênh, kích thƣớc ô nhớ, tham số bộ đếm ví dụ chúng ta có thể thiết kế bộ cộng cho các hạng tử có độ dài bit thay đổi, số bit đƣợc thể hiện là hằng số trong khai báo generic (xem ví dụ dƣới đây) - Khai báo cổng vào ra: liệt kê tất cả các cổng giao tiếp của khối thiết kế, các cổng có thể hiểu là các kênh dữ liệu động của thiết kế để phân biệt với các tham số tĩnh trong khai báo generic. kiểu của các cổng có thể là: - in: cổng vào, 45
- - out: cổng ra, - inout vào ra hai chiều. - buffer: cổng đệm có thể sử dụng nhƣ tín hiệu bên trong và output. - linkage: Có thể làm bất kỳ các cổng nào kể trên. Ví dụ cho khai báo thực thể nhƣ sau: entity adder is generic ( N : natural := 32); port ( A : in bit_vector(N-1 downto 0); B : in bit_vector(N-1 downto 0); cin : in bit; Sum : out bit_vector(N-1 downto 0); Cout : out bit); end entity adder ; Đoạn mã trên khai báo một thực thể cho khối cộng hai số, trong khai báo trên N là tham số tĩnh generic chỉ độ dài bit của các hạng tử, giá trị ngầm định N = 32, việc khai báo giá trị ngầm định là không bắt buộc. Khi khối này đƣợc sử dụng trong khối khác nhƣ một khối con khác thì có thể thay đổi giá trị của N để thu đƣợc thiết kế theo mong muốn. Về các cổng vào ra, khối cộng hai số nguyên có 3 cổng vào A, B N-bit là các hạng tử và cổng cin là bít nhớ từ bên ngoài. Hai cổng ra là Sum N-bit là tổng và bít nhớ ra Cout. Khai báo thực thể có thể chứa chỉ mình khai báo cổng nhƣ sau: entity full_adder is port ( X, Y, Cin : in bit; Cout, Sum : out bit ); end full_adder ; Khai báo thực thể không chứa cả khai báo generic lẫn khai báo port vẫn đƣợc xem là hợp lệ, ví dụ những khai báo thực thể sử dụng để mô phỏng kiểm tra thiết kế thƣờng đƣợc khai báo nhƣ sau: entity TestBench is end TestBench; Ví dụ về cổng dạng buffer và inout: Cổng buffer đƣợc dùng khi tín hiệu đƣợc sử dụng nhƣ đầu ra đồng thời nhƣ một tín hiệu bên trong của khố thiết kế, điển hình nhƣ trong các mạch dãy làm việc đồng bộ. Xét ví dụ sau về bộ cộng tích lũy 4-bit đơn giản sau (accumulator): library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_unsigned.ALL; use IEEE.STD_LOGIC_arith.ALL; 46
- entity accumulator is port( data : in std_logic_vector(3 downto 0); nRST : in std_logic; CLK : in std_logic; acc : buffer std_logic_vector(3 downto 0) ); end accumulator; architecture behavioral of accumulator is begin ac : process (CLK) begin if CLK = '1' and CLK'event then if nRST = '1' then acc <= "0000"; else acc <= acc + data; end if; end if; end process ac; end behavioral; Bộ cộng tích lũy sau mỗi xung nhịp CLK sẽ cộng giá trị hiện có lƣu trong acc với giá trị ở đầu vào data, tín hiệu nRST dùng để thiết lập lại giá trị bằng 0 cho acc. Nhƣ vậy acc đóng vai trò nhƣ thanh ghi kết quả đầu ra cũng nhƣ giá trị trung gian đƣợc khai báo dƣới dạng buffer. Trên thực tế thay vì dùng cổng buffer thƣờng sử dụng một tín hiệu trung gian, khi đó cổng acc có thể khai báo nhƣ cổng ra bình thƣờng, cách sử dụng nhƣ vậy sẽ tránh đƣợc một số lỗi có thể phát sinh khi tổng hợp thiết kế do khai báo buffer gây ra. Ví dụ sau đây là mô tả VHDL của một khối đệm ba trạng thái 8-bit, sử dụng khai báo cổng INOUT. Cổng ba trạng thái đƣợc điều khiển bởi tín hiệu OE, khi OE bằng 0 giá trị của cổng là trạng thái trở kháng cao “ZZZZZZZZ”, khi OE bằng 1 thì cổng kết nối đầu vào inp với outp. library ieee; use ieee.std_logic_1164.ALL; entity bidir is port( bidir : inout std_logic_vector (7 downto 0); oe, clk : in std_logic_LOGIC; 47
- inp : in std_logic_vector (7 downto 0); outp : out std_logic_vector (7 downto 0) ); END bidir; architecture behav of bidir is signal a : std_logic_vector (7 downto 0); signal b : std_logic_vector (7 downto 0); begin process(clk) begin if clk = '1' and clk'event then a <= inp; outp <= b; end if; end process; process (oe, bidir) begin if( oe = '0') then bidir <= "ZZZZZZZZ"; b <= bidir; else bidir <= a; b <= bidir; end if; end process; end maxpld; * Trong thành phần của khai báo thực thể ngoài khai báo cổng và khai báo generic còn có thể có hai thành phần khác là khai báo kiểu dữ liệu, thư viện người dùng chung, chương trình con Và phần phát biểu chung chỉ chứa các phát biểu đồng thời. Các thành phần này nếu có sẽ có tác dụng đối với tất cả các kiến trúc của thực thể. Chi tiết hơn về các thành phần khai báo này có thể xem trong [5] IEEE VHDL Standard Language reference (2002 Edition). 2.3. Mô tả kiến trúc Mô tả kiến trúc (ARCHITECTURE) là phần mô tả chính của một khối thiết kế VHDL, nếu nhƣ mô tả entity chỉ mang tính chất khai báo về giao diện của thiết kế thì mô tả kiến trúc chứa nội dung về chức năng của đối tƣợng thiết kế. Cấu trúc của mô tả kiến trúc tổng quát nhƣ sau: architecture identifier of entity_name is [ declarations] begin 48
- [ statements ] end identifier ; Trong đó - identifier là tên gọi của kiến trúc, thông thƣờng để phân biệt các kiểu mô tả thƣờng dùng các tên behavioral cho mô tả hành vi, dataflow cho mô tả luồng dữ liệu, structure cho mô tả cấu trúc tuy vậy có thể sử dụng một tên gọi hợp lệ bất kỳ nào khác. - [declarations] có thể có hoặc không chứa các khai báo cho phép nhƣ sau: Khai báo và mô tả chƣơng trình con (subprogram) Khai báo kiểu dữ liệu con (subtype) Khai báo tín hiệu (signal), hằng số (constant), file Khai báo khối con (component) -[statements] phát biểu trong khối {begin end process;} chứa các phát biểu đồng thời (concurrent statements) hoặc các khối process chứa các phát biểu tuần tự (sequential statements). Có ba dạng mô tả cấu trúc cơ bản là mô tả hành vi (behavioral), mô tả luồng dữ liệu (dataflow) và mô tả cấu trúc (structure). Trên thực tế trong mô tả kiến trúc của những khối phức tạp thì sử dụng kết hợp cả ba dạng mô tả này. Để tìm hiểu về ba dạng mô tả kiến trúc ta sẽ lấy ví dụ về khối full_adder có khai báo entity nhƣ sau: entity full_adder is port ( A : in std_logic; B : in std_logic; cin : in std_logic; Sum : out std_logic; Cout : out std_logic); end entity full_adder; 2.3.1. Mô tả hành vi Đối với thực thể full_adder nhƣ trên kiến trúc hành vi (behavioral) đƣợc viết nhƣ sau architecture behavioral of full_adder is begin add: process (A,B,Cin) begin if (a ='0' and b='0' and Cin = '0') then S <= '0'; 49
- Cout <='0'; elsif (a ='1' and b='0' and Cin = '0') or (a ='0' and b='1' and Cin = '0') or (a ='0' and b='0' and Cin = '1') then S <= '1'; Cout <='0'; elsif (a ='1' and b='1' and Cin = '0') or (a ='1' and b='0' and Cin = '1') or (a ='0' and b='1' and Cin = '1') then S <= '0'; Cout <= '1'; elsif (a ='1' and b='1' and Cin = '1') then S <= '1'; Cout <= '1'; end if; end process add; end behavioral; Mô tả hành vi gần giống nhƣ mô tả bằng lời cách thức tính toán kết quả đầu ra dựa vào các giá trị đầu vào. Toàn bộ mô tả hành vi phải đƣợc đặt trong một khối quá trình {process (sensitive list) end process;} ý nghĩa của khối này là nó tạo một quá trình để ―theo dõi‖ sự thay đổi của tất cả các tín hiệu có trong danh sách tín hiệu (sensitive list), khi có bất kỳ một sự thay đổi giá trị nào của tín hiệu trong danh sách thì nó sẽ thực hiện quá trình tính toán ra kết quả tƣơng ứng ở đầu ra. Chính vì vậy trong đó rất hay sử dụng các phát biểu tuần tự nhƣ if, case, hay các vòng lặp loop. Việc mô tả bằng hành vi không thể hiện rõ đƣợc cách thức cấu tạo phần cứng của vi mạch nhƣ các dạng mô tả khác và tùy theo những cách viết khác nhau thì có thể thu đƣợc những kết quả tổng hợp khác nhau. Trong các mạch dãy đồng bộ, khối làm việc đồng bộ thƣờng đƣợc mô tả bằng hành vi, ví dụ nhƣ trong đoạn mã sau mô tả thanh ghi sau: process(clk) begin if clk'event and clk='1' then Data_reg <= Data_in; end if; end process; 2.3.2. Mô tả luồng dữ liệu Mô tả luồng dữ liệu (dataflow)là dạng mô tả tƣơng đối ngắn gọn và rất hay đƣợc sử dụng khi mô tả các khối mạch tổ hợp. Các phát biểu trong khối 50
- begin end là các phát biểu đồng thời (concurrent statements) nghĩa là không phụ thuộc thời gian thực hiện của nhau, nói một cách khác không có thứ tự ƣu tiên trong việc sắp xếp các phát biểu này đứng trƣớc hay đứng sau trong đoạn mã mô tả. Ví dụ cho khối full_adder thì mô tả luồng dữ liệu nhƣ sau: architecture dataflow of full_adder is begin sum <= (a xor b) xor Cin; Cout <= (a and b) or (Cin and (a xor b)); end dataflow; 2.3.3. Mô tả cấu trúc Mô tả cấu trúc (structure) là mô tả sử dụng các mô tả có sẵn dƣới dạng khối con (component). Dạng mô tả này cho kết quả sát với kết quả tổng hợp nhất. Theo mô tả luồng dữ liệu nhƣ ở trên ta thấy dùng hai cổng XOR, một cổng OR và 2 cổng AND để thực hiện thiết kế giống nhƣ hình dƣới đây: A B Cout Sum Cin Hình 2-2. Sơ đồ logic của khối cộng đầy đủ (FULL_ADDER) Trƣớc khi viết mô tả cho full_adder cần phải viết mô tả cho các phần tử cổng AND, OR, XOR nhƣ sau 2 input AND gate library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity AND2 is port( in1, in2 : in std_logic; out1 : out std_logic ); end AND2; architecture model_conc of AND2 is begin out1 <= in1 and in2; end model_conc; library IEEE; use IEEE.STD_LOGIC_1164.ALL; 51
- 2 input OR gate entity OR2 is port ( in1, in2 : in std_logic; out1 : out std_logic ); end OR2; architecture model_conc2 of AND2 is begin out1 <= in1 or in2; end model_conc2; 2 input XOR gate library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity XOR2 is port ( in1, in2 : in std_logic; out1 : out std_logic); end XOR2; architecture model_conc2 of XOR2 is begin out1 <= in1 xor in2; end model_conc2; Sau khi đã có các cổng trên có thể thực hiện viết mô tả cho full_adder nhƣ sau architecture structure of full_adder is signal t1, t2, t3: std_logic; component AND2 port ( in1, in2 : in std_logic; out1 : out std_logic ); end component; component OR2 port ( in1, in2 : in std_logic; out1 : out std_logic); end component; component XOR2 port ( in1, in2 : in std_logic; 52
- out1 : out std_logic ); end component; begin u1 : XOR2 port map (a, b, t1) u2 : XOR2 port map (t1, Cin, Sum) u3 : AND2 port map (t1, Cin, t2) u4 : AND2 port map (a, b, t3) u5 : OR2 port map (t3, t2, Cout); end structure; Nhƣ vậy mô tả cấu trúc tuy khá dài nhƣng là mô tả cụ thể về cấu trúc mạch, ƣu điểm của phƣơng pháp này là khi tổng hợp trên thƣ viện cổng sẽ cho ra kết quả đúng với ý tƣởng thiết kế nhất. Với mô tả full_adder nhƣ trên thì gần chắc chắn trình tổng hợp đƣa ra sơ đồ logic sử dụng 2 cổng XOR, hai cổng AND và 1 cổng OR. Mặt khác mô tả cấu trúc cho phép gộp nhiều mô tả con vào một khối thiết kế lớn mà vẫn giữ đƣợc cấu trúc mã rõ ràng và khoa học. Nhƣợc điểm là không thể hiện rõ ràng chức năng của mạch nhƣ hai mô tả ở các phần trên. Ở ví dụ trên có sử dụng khai báo cài đặt khối con, chi tiết về khai báo này xem trong mục 7.5. 2.4. Khai báo cấu hình Một thực thể có thể có rất nhiều kiến trúc khác nhau. Bên cạnh đó cấu trúc của ngôn ngữ VHDL cho phép sử dụng các khối thiết kế theo kiểu lồng ghép, vì vậy đối với một thực thể bất kỳ cần có thêm các mô tả để quy định việc sử dụng các kiến trúc khác nhau. Khai báo cấu hình (Configuration declaration) đƣợc sử dụng để chỉ ra kiến trúc nào sẽ đƣợc sử dụng trong thiết kế. Cách thứ nhất để sử dụng khai báo cấu hình là sử dụng trực tiếp khai báo cấu hình bằng cách tạo một đoạn mã cấu hình độc lập không thuộc một thực thể hay kiến trúc nào theo cấu trúc: configuration identifier of entity_name is [declarations] [block configuration] end configuration identifier; Ví dụ sau tạo cấu hình có tên add32_test_config cho thực thể add32_test, cấu hình này quy định cho kiến trúc có tên circuits của thực thể add32_test, khi cài đặt các khối con có tên add32 sử dụng kiến trúc tƣơng ứng là WORK.add32(circuits), với mọi khối con add4c của thực thể add32 thì sử dụng 53
- kiến trúc WORK.add4c(circuit), tiếp đó là quy định mọi khối con có tên fadd trong thực thể add4c sử dụng kiến trúc có tên WORK.fadd(circuits). configuration add32_test_config of add32_test is for circuits of add32_test for all: add32 use entity WORK.add32(circuits); for circuits of add32 for all: add4c use entity WORK.add4c(circuits); for circuits of add4c for all: fadd use entity WORK.fadd(circuits); end for; end for; end for; end for; end for; end for; end configuration add32_test_config; Cặp lệnh cơ bản của khai báo cấu hình là cặp lệnh for use end for có tác dụng quy định cách thức sử dụng các kiến trúc khác nhau ứng với các khối khác nhau trong thiết kế. Bản thân configuration cũng có thể đƣợc sử dụng nhƣ đối tƣợng của lệnh use, ví dụ: configuration adder_behav of adder4 is for structure for all: full_adder use entity work.full_adder (behavioral); end for; end for; end configuration; Với một thực thể có thể khai báo nhiều cấu hình khác nhau tùy theo mục đích sử dụng. Sau khi đƣợc khai báo nhƣ trên và biên dịch thì sẽ xuất hiện thêm trong thƣ viện các cấu hình tƣơng ứng của thực thể. Các cấu hình khác nhau xác định các kiến trúc khác nhau của thực thể và có thể đƣợc mô phỏng độc lập. Nói một cách khác cấu hình là một đối tƣợng có cấp độ cụ thể cao hơn so với kiến trúc. Cách thức thứ hai để quy định việc sử dụng kiến trúc là dùng trực tiếp cặp lệnh for use end for; nhƣ minh họa dƣới đây, cách thức này cho phép khai báo cấu hình trực tiếp bên trong một kiến trúc cụ thể: library IEEE; 54
- use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity adder4 is port( A : in std_logic_vector(3 downto 0); B : in std_logic_vector(3 downto 0); CI : in std_logic; SUM : out std_logic_vector(3 downto 0); CO : out std_logic ); end adder4; architecture structure of adder4 is signal C: std_logic_vector(2 downto 0); declaration of component full_adder component full_adder port( A : in std_logic; B : in std_logic; Cin : in std_logic; S : out std_logic; Cout : out std_logic ); end component; for u0: full_adder use entity work.full_adder(behavioral); for u1: full_adder use entity work.full_adder(dataflow); for u2: full_adder use entity work.full_adder(structure); for u3: full_adder use entity work.full_adder(behavioral); begin design of 4-bit adder u0: full_adder port map (A => A(0), B => B(0), Cin => CI, S =>Sum(0), Cout => C(0)); u1: full_adder port map (A => A(1), B => B(1), Cin => C(0), S =>Sum(1), Cout => C(1)); u2: full_adder port map (A => A(2), B => B(2), 55
- Cin => C(1), S =>Sum(2), Cout => C(2)); u3: full_adder port map (A => A(3), B => B(3), Cin => C(2), S =>Sum(3), Cout => CO); end structure; Ở ví dụ trên một bộ cộng 4 bit đƣợc xây dựng từ 4 khối full_adder nhƣng với các kiến trúc khác nhau. Khối đầu tiên dùng kiến trúc hành vi (behavioral), khối thứ hai là kiến trúc kiểu luồng dữ liệu (dataflow), khối thứ 3 là kiến trúc kiểu cấu trúc (structure), và khối cuối cùng là kiến trúc kiểu hành vi. 3. Chương trình con và gói 3.1. Thủ tục Chƣơng trình con (subprogram) là các đoạn mã dùng để mô tả một thuật toán, phép toán dùng để xử lý, biến đổi, hay tính toán dữ liệu. Có hai dạng chƣơng trình con là thủ tục (procedure) và hàm (function). Thủ tục thƣờng dùng để thực hiện một tác vụ nhƣ biến đổi, xử lý hay kiểm tra dữ liệu, hoặc các tác vụ hệ thống nhƣ đọc ghi file, truy xuất kết quả ra màn hình, kết thúc mô phỏng, theo dõi giá trị tín hiệu . Khai báo của thủ tục nhƣ sau: procedure identifier [(formal parameter list)] is [declarations] begin sequential statement(s) end procedure identifier; ví dụ: procedure print_header ; procedure build ( A : in constant integer; B : inout signal bit_vector; C : out variable real; D : file); Trong đó formal parameter list chứa danh sách các biến, tín hiệu, hằng số, hay dữ liệu kiểu FILE, kiểu ngầm định là biến. Các đối tƣợng trong danh sách này trừ dạng file có thể đƣợc khai báo là dạng vào (in), ra (out), hay hai chiều (inout), kiểu ngầm định là in. Xét vi dụ đầy đủ dƣới đây: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use STD.TEXTIO.all; 56
- entity compare is port( res1, res2 : in bit_vector(3 downto 0) ); end compare; architecture behavioral of compare is procedure print_to_file( val1, val2 : in bit_vector(3 downto 0); FILE fout : text) is use STD.TEXTIO.all; variable str: line; begin WRITE (str, string'("val1 = ")); WRITE (str, val1); WRITE (str, string'(" val2 = ")); WRITE (str, val2); if val1 = val2 then WRITE (str, string'(" OK")); elsif WRITE (str, string'(" TEST FAILED")); end if; WRITELINE(fout, str); WRITELINE(output, str); end procedure print_to_file; FILE file_output : text open WRITE_MODE is "test_log.txt"; start here begin proc_compare: print_to_file(res1, res2, file_output); end behavioral; Trong ví dụ trên chƣơng trình con dùng để so sánh và ghi kết quả so sánh của hai giá trị kết quả res1, res2 vào trong file văn bản có tên "test_log.txt". Phần khai báo của hàm đƣợc đặt trong phần khai báo của kiến trúc nhƣng nếu hàm đƣợc gọi trực tiếp trong kiến trúc nhƣ ở trên thì khai báo này có thể bỏ đi. Thân chƣơng trình con đƣợc viết trực tiếp trong phần khai báo của kiến trúc và đƣợc gọi trực tiếp cặp begin end behavioral. 57
- 3.2. Hàm Hàm (function) thƣờng dùng để tính toán kết quả cho một tổ hợp đầu vào. Khai báo của hàm có cú pháp nhƣ sau: function identifier [parameter list] return a_type; ví dụ function random return float; function is_even ( A : integer) return boolean; Danh sách biến của hàm cũng đƣợc cách nhau bởi dấu ―;‖ nhƣng điểm khác là trong danh sách này không có chỉ rõ dạng vào/ra của biến mà ngầm định tất cả là đầu vào. Kiểu dữ liệu đầu ra của hàm đƣợc quy định sau từ khóa return. Cách thức sử dụng hàm cũng tƣơng tự nhƣ trong các ngôn ngữ lập trình bậc cao khác. Xét một ví dụ đầy đủ dƣới đây: library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity function_example is end function_example; architecture behavioral of function_example is type bv4 is array (3 downto 0) of std_logic; function mask(mask, val1 : in bv4) return bv4; signal vector1 : bv4 := "0011"; signal mask1 : bv4 := "0111"; signal vector2 : bv4; function mask(mask, val1 : in bv4) return bv4 is variable temp : bv4; begin temp(0) := mask(0) and val1(0); temp(1) := mask(1) and val1(1); temp(2) := mask(2) or val1(2); temp(3) := mask(3) or val1(3); return temp; end function mask; start here begin masking: vector2 <= mask(vector1, mask1); end behavioral; Ví dụ trên minh họa cho việc sử dụng hàm để thực hiện phép tính mặt nạ (mask) đặc biệt trong đó hai bit thấp của giá trị đầu vào đƣợc thực hiện phép logic OR với giá trị mask còn hai bit cao thì thực hiện mask bình thƣờng với 58
- phép logic AND. Phần khai báo của hàm đƣợc đặt trong phần khai báo của kiến trúc, nếu hàm đƣợc gọi trực tiếp trong kiến trúc nhƣ ở trên thì khai báo này có thể bỏ đi. Phần thân của hàm đƣợc viết trong phần khai báo của kiến trúc trƣớc cặp {begin end behavioral}. Khi gọi hàm trong phần thân của kiến trúc thì giá trị trả về của hàm phải đƣợc gán cho một tín hiệu, ở ví dụ trên là vector2. 3.3. Gói Gói (package) là tập hợp các kiểu dữ liệu, hằng số, biến, các chƣơng trình con và hàm dùng chung trong thiết kế. Một cách đơn giản gói là một cấp thấp hơn của thƣ viện, một thƣ viện cấu thành từ nhiều gói khác nhau. Ngoài các gói chuẩn của các thƣ viên chuẩn nhƣ trình bày ở 2.1, ngôn ngữ VHDL cho phép ngƣời dùng tạo ra các gói riêng tùy theo mục đích sử dụng. Một gói bao gồm khai báo gói và phần thân của gói. Khai báo gói có cấu trúc nhƣ sau: package identifier is [ declarations] end package identifier ; Phần khai báo chỉ chứa các khai báo về kiểu dữ liệu, biến dùng chung, hằng và khai báo của hàm hay thủ tục nếu có. Phần thân gói có cú pháp nhƣ sau: package body identifier is [ declarations] end package body identifier ; Phần thân gói chứa các mô tả chi tiết của hàm hay thủ tục. Ngoài ra gói còn đƣợc dùng để chứa các khai báo component dùng chung cho các thiết kế lớn. Ví dụ các phần tử nhƣ khối cộng, thanh ghi, khối dịch, thanh ghi dịch, bộ đếm, khối chọn kênh là các khối cơ bản cấu thành của hầu hết các khối thiết kế phức tạp, vì vậy sẽ rất tiện dụng khi ―đóng gói‖ tất cả các thiết kế này nhƣ một thƣ viện dùng chung giống nhƣ các gói chuẩn và sử dụng trong các thiết kế lớn khác nhau với điều kiện các khối này có khai báo sử dụng gói trên. Ví dụ đầy đủ một gói có chứa hai chƣơng trình con liệt kê ở 3.1 và 3.2 và chứa các khai báo thiết kế dùng chung nhƣ sau: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use STD.TEXTIO.all; package package_example is type bv4 is array (3 downto 0) of std_logic; function mask(mask, val1 : in bv4) return bv4; 59
- procedure print_to_file(val1, val2 : in bit_vector(3 downto 0); FILE fout :text); end package package_example; package body package_example is function mask(mask, val1 : in bv4) return bv4; signal vector1 : bv4 := "0011"; signal mask1 : bv4 := "0111"; signal vector2 : bv4; component adder_sub is generic (N: natural := 32); port( SUB : in std_logic; Cin : in std_logic; A : in std_logic_vector(N-1 downto 0); B : in std_logic_vector(N-1 downto 0); SUM : out std_logic_vector(N-1 downto 0) ; Cout : out std_logic ); end component; component counter is generic (N: natural := 3); PORT( clk : in std_logic; reset : in std_logic; counter_enable : in std_logic; end_num : in std_logic_vector (N-1 downto 0); cnt_end : out std_logic ); end component; component reg is generic (N: natural := 32); port( D : in std_logic_vector(N-1 downto 0); Q : out std_logic_vector(N-1 downto 0); CLK : in std_logic; RESET : in std_logic ); end component; component mux is generic (N: natural := 32); port( Sel : in std_logic; Din1 : in std_logic_vector(N-1 downto 0); 60
- Din2 : in std_logic_vector(N-1 downto 0); Dout : out std_logic_vector(N-1 downto 0) ); end component; function mask(mask, val1 : in bv4) return bv4 is variable temp : bv4; begin temp(0) := mask(0) and val1(0); temp(1) := mask(1) and val1(1); temp(2) := mask(2) or val1(2); temp(3) := mask(3) or val1(3); return temp; end function mask; procedure print_to_file( val1, val2 : in bit_vector(3 downto 0); FILE fout : text) is use STD.TEXTIO.all; variable str: line; begin WRITE (str, string'("val1 = ")); WRITE (str, val1); WRITE (str, string'(" val2 = ")); WRITE (str, val2); if val1 = val2 then WRITE (str, string'(" OK")); elif WRITE (str, string'(" TEST FAILED")); end if; WRITELINE(fout, str); WRITELINE(output, str); end procedure print_to_file; end package body package_example; Để sử dụng gói này trong các thiết kế thì phải khai báo thƣ viện và gói sử dụng tƣơng tự nhƣ trong các gói chuẩn ở phần khai báo thƣ viện. Vì theo ngầm định các gói này đƣợc biên dịch vào thƣ viện có tên là work nên khai báo nhƣ sau: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use STD.TEXTIO.all; library work; 61
- use work.package_example.all; entity pck_example is port( res1, res2 : in bit_vector(3 downto 0) ); end pck_example; architecture behavioral of pck_example is signal vector2 : bv4; signal vector1 : bv4 := "0011"; signal mask1 : bv4 := "0111"; FILE file_output : text open WRITE_MODE is "test_log.txt"; begin proc_compare: print_to_file(res1, res2, file_output); masking : vector2 <= mask(vector1, mask1); end behavioral; 4. Đối tượng dữ liệu, kiểu dữ liệu 4.1. Đối tượng dữ liệu Trong VHDL có phân biệt 3 loai đối tƣợng dữ liệu là biến, hằng và tín hiệu. Các đối tƣợng đƣợc khai báo theo cú pháp Object_type identifier : type [:= initial value]; Trong đó object_type có thể là Variable, Constant hay Signal. 4.1.1. Hằng Hằng (Constant) là những đối tƣợng dữ liệu dùng khởi tạo để chứa các giá trị xác định trong quá trình thực hiện. Hằng có thể đƣợc khai báo trong các gói, thực thể, kiến trúc, chƣơng trình con, các khối và quá trình. Cú pháp constant identifier : type [range value] := value; Ví dụ; constant PI : REAL := 3.141569; constant vector_1 : std_logic_vector(8 downto 0):= “11111111”; 62
- 4.1.2. Biến Biến (Variable) là những đối tƣợng dữ liệu dùng để chứa các kết quả trung gian, biến chỉ có thể đƣợc khai báo bên trong các quá trình hoặc chƣơng trình con. Khai báo biến bao giờ cũng đi kèm với kiểu, có thể có xác định giới hạn giá trị và có giá trị khởi tạo ban đầu, nếu không có giá trị khởi tạo ban đầu thì biến sẽ nhận giá trị khởi tạo là giá trị nhỏ nhất trong miền giá trị. Cú pháp variable identifier : type [range value] [:= initial value]; Ví dụ variable count : integer range 0 to 15 := 0; variable vector_bit : std_logic_vector(8 downto 0); 4.1.3. Tín hiệu Tín hiệu (Signal) là các đối tƣợng dữ liệu dùng để kết nối giữa các khối logic hoặc để đồng bộ các quá trình. Tín hiệu có thể đƣợc khai báo trong phần khai báo gói, khi đó ta sẽ có tín hiệu là toàn cục, khai báo trong thực thể khi đó tín hiệu là tín hiệu toàn cục của thực thể, trong khai báo kiến trúc, và khai báo trong các khối. Các tín hiệu tuyệt đối không đƣợc khai báo trong các quá trình và các chƣơng trình con mà chỉ đƣợc sử dụng trong chúng, đặc điểm này thể hiện sự khác biệt rõ nhất giữa biến và tín hiệu. Cú pháp signal identifier : type [range value] [:= initial value]; Ví dụ: signal a : std_logic := „0‟; signal vector_b : std_logic_vector(31 downto 0); 4.2. Kiểu dữ liệu 4.2.1. Các kiểu dữ liệu tiền định nghĩa Trong các kiểu dữ liệu của VHDL có chia ra dữ liệu tiền định nghĩa và dữ liệu ngƣời dùng định nghĩa. Dữ liệu tiền định nghĩa là dữ liệu đƣợc định nghĩa trong các bộ thƣ viện chuẩn của VHDL, dữ liệu ngƣời dùng định nghĩa là các dữ liệu đƣợc định nghĩa lại dựa trên cơ sở dữ liệu tiền định nghĩa, phù hợp cho từng trƣờng hợp sử dụng khác nhau. Các dữ liệu tiền định nghĩa đƣợc mô tả trong các thƣ viện STD, và IEEE, cụ thể nhƣ sau: 63
- - BIT, và BIT_VECTOR, đƣợc mô tả trong thƣ viện STD.STANDARD, BIT chỉ nhận các giá trị ‗0‘, và ‗1‘. Ngầm định nếu nhƣ các biến dạng BIT không đƣợc khởi tạo giá trị ban đầu thì sẽ nhận giá trị 0. Vì BIT chỉ nhận các giá trị tƣờng minh nên không phù hợp khi sử dụng để mô tả thực thể phần cứng thật, thay vì đó thƣờng sử dụng các kiểu dữ liệu STD_LOGIC và STD_ULOGIC. Tuy vậy trong một số trƣờng hợp ví dụ các lệnh của phép dịch, hay lệnh WRITE chỉ hỗ trợ cho BIT và BIT_VECTOR mà không hỗ trợ STD_LOGIC và STD_LOGIC_VECTOR. - STD_ULOGIC và STD_ULOGIC_VECTOR, STD_LOGIC, STD_LOGIC_VECTOR đƣợc mô tả trong thƣ viện IEEE.STD_LOGIC_1164, STD_ULOGIC, và STD_LOGIC có thể nhận một trong 9 giá trị liệt kê ở bảng sau: Bảng 2-1 Giá trị của kiểu dữ liệu STD_LOGIC/STD_ULOGIC ‗U‘ Không xác định - (Unresolved) 'X' X Bắt buộc '0' 0 Bắt buộc '1' 1 Bắt buộc 'Z' Trở kháng cao - 'W' X Yếu 'L' 0 Yếu 'H' 1 Yếu '-' Không quan tâm - Tên đầy đủ của STD_ULOGIC là Standard Unresolved Logic, hay kiểu logic chuẩn chƣa quy định về cách kết hợp các giá trị logic với nhau,do vậy đối với kiểu STD_ULOGIC thì khi thiết kế không cho phép để một tín hiệu có nhiều nguồn cấp. Kiểu STD_LOGIC là kiểu dữ liệu cũng có thể nhận một trong 9 giá trị logic nhƣ trên nhƣng đã có quy định cách thức các giá trị kết hợp với nhau bằng hàm resolved. Nếu quan sát trong file stdlogic.vhd ta sẽ gặp đoạn mã mô tả hàm này, hai tín hiệu giá trị kiểu STD_LOGIC khi kết hợp với nhau sẽ thu đƣợc 1 tín hiệu giá trị logic theo quy tắc trong bảng rosolved table dƣới đây. SUBTYPE std_logic IS resolved std_ulogic; TYPE stdlogic_table IS ARRAY(std_ulogic, std_ulogic) OF std_ulogic; 64
- CONSTANT resolution_table : stdlogic_table := ( | U X 0 1 Z W L H - ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), | U | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), | X | ( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), | 0 | ( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), | 1 | ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), | Z | ( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), | W | ( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), | L | ( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), | H | ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) | - | ); FUNCTION resolved ( s : std_ulogic_vector ) RETURN std_ulogic IS VARIABLE result : std_ulogic := 'Z'; weakest state default BEGIN IF (s'LENGTH = 1) THEN RETURN s(s'LOW); ELSE FOR i IN s'RANGE LOOP result := resolution_table(result, s(i)); END LOOP; END IF; RETURN result; END resolved; Ví dụ đoạn mã sau đây sẽ gây ra lỗi biên dịch: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; entity logic_expample is port( A : in std_ulogic_vector(8 downto 0); U : out std_ulogic_vector(8 downto 0) ); end logic_expample; architecture dataflow of logic_expample is begin U <= A; U <= "X01ZWLH-1"; 65
- end dataflow; Lỗi biên dịch sẽ báo rằng tín hiệu U có hai nguồn đầu vào. # Error: logic_example.vhd(19): Nonresolved signal 'u' has multiple sources. Nhƣ đối với đoạn mã trên nếu khai báo U là tín hiệu dạng STD_LOGIC thì vẫn biên dịch đƣợc bình thƣờng. Trên thực tế tùy vào đối tƣợng cụ thể mà dùng các kiểu tƣơng ứng nhƣng để đảm bảo tránh việc ghép nhiều đầu vào chung (việc này bắt buộc tránh khi thiết kế mạch thật), thì nên sử dụng STD_ULOGIC. Các dữ liệu tiền định nghĩa khác có trong ngôn ngữ VHDL liệt kê ở dƣới đây: - BOOLEAN: có các giá trị TRUE, FALSE (đúng/sai). -INTEGER: số nguyên 32 bits ( từ -2.147.483.647 đến +2.147.483.647) - NATURAL: số nguyên không âm ( từ 0 đến +2.147.483.647) - REAL: số thực nằm trong khoảng ( từ -1.0E38 đến +1.0E38). -TIME: sử dụng đối với các đại lƣợng vật lý, nhƣ thời gian,điện áp, Hữu ích trong mô phỏng - CHARACTER: ký tự ASCII. -FILE_OPEN_KIND: kiểu mở file gồm các giá trị MODE, WRITE_MODE, APPEND_MODE. -FILE_OPEN_STATUS: Trạng thái mở file với các giá trị OPEN_OK, STATUS_ERROR, NAME_ERROR, MODE_ERROR. -SEVERITY_LEVEL: trạng thái lỗi với các giá trị NOTE, WARNING, ERROR, FAILURE. 4.2.2. Các kiểu dữ liệu vô hướng Dữ liệu vô hƣớng trong VHDL (Scalar types) bao gồm kiểu liệt kê (enumeration), kiểu nguyên (integer), kiểu số thực dấu phảy động (real), kiểu dữ liệu vật lý (physical type). Các kiểu dữ liệu dƣới đây đƣợc xét nhƣ các đối tƣợng dữ liệu ngƣời dùng định nghĩa từ các đối tƣợng dữ liệu tiền định nghĩa ở trên. Kiểu liệt kê Kiểu liệt kê (Enumeration) đƣợc định nghĩa bằng cách liệt kê tất cả các giá trị có thể có của kiểu, khai báo nhƣ sau type enum_name is (enum_literals list); Ví dụ: type MULTI_LEVEL_LOGIC is (LOW, HIGH, RISING, FALLING,AMBIGUOUS); 66
- type BIT is ('0','1'); type SWITCH_LEVEL is ('0','1','X'); Các kiểu liệt kê định sẵn trong VHDL là: -kiểu ký tự (CHARACTER). -kiểu (BIT) gồm hai giá trị 0, 1. -kiểu logic (BOOLEAN) gồm các giá trị TRUE, FALSE. -kiểu SEVERITY kiểu cảnh báo lỗi gồm các giá trị NOTE, WARNING, ERROR, FAILURE. -kiểu dạng và trạng thái File (FILE_OPEN_KIND với các giá trị READ_MODE, WRITE_MODE, APPEND_MODE, kiểu FILE_OPEN_STATUS với các giá trị OPEN_OK, STATUS_ERROR, NAME_ERROR, MODE_ERROR). Kiểu số nguyên Kiểu số nguyên (integer) đƣợc định nghĩa sẵn trong VHDL là INTEGER có giới hạn từ –2147483647 đến +2147483647. Các phép toán thực hiện trên kiểu nguyên là +, -, *, /. Các kiểu nguyên thứ sinh đƣợc khai báo theo cú pháp sau: type identifier is range interger_range; Trong đó interger_range là một miền con của tập số nguyên, các giá trị giới hạn của miền con phải viết dƣới dạng số nguyên và có thể nhận giá trị âm hoặc dƣơng, ví dụ: type word_index is range 30 downto 0; type TWOS_COMPLEMENT_INTEGER is range –32768 to 32767; Kiểu số thực Kiểu số thực (Real) đƣợc định nghĩa sẵn trong VHDL là Real có giới hạn từ –1.0E38 tới +1.0E38. Các kiểu thực thứ sinh đƣợc khai báo theo cú pháp sau: type identifier is range real_range; Trong đó real_range là miền con của miền số thực các giá trị giới hạn của miền này có thể là các giá trị dƣơng hoặc âm đƣợc viết bằng một trong những dạng cho phép của số thực nhƣ dạng dấu phẩy động hay dạng thập phân và không nhất thiết phải giống nhau, ví dụ: type my_float1 is range 1.0 to 1.0E6; type my_float2 is range -1.0e5 to 1.0E6; Kiểu giá trị đại lượng vật lý Kiểu giá trị đại lƣợng vật lý (physical) đƣợc dùng để định nghĩa các đơn vị vật lý nhƣ thời gian, khoảng cách, diện tích, Chỉ có một kiểu giá trị đại lƣợng vật lý đƣợc định nghĩa sẵn trong VHDL là kiểu TIME 67
- type Time is range implementation defined ; units fs; femtosecond ps = 1000 fs; picosecond ns = 1000 ps; nanosecond us = 1000 ns; microsecond ms = 1000 us; millisecond sec = 1000 ms; second min = 60 sec; minute hr = 60 min; hour end units; Các kiểu giá trị đại lƣợng vật lý đƣợc khai báo với cú pháp tƣơng tự nhƣ trên, sau từ khóa units là đơn vị chuẩn và các đơn vị thứ sinh bằng một số nguyên lần các đơn vị chuẩn, danh sách các đơn vị đƣợc kết thúc bởi từ khóa end units, ví dụ: type distance is range 0 to 1E16 units Ang; angstrom nm = 10 Ang; nanometer um = 1000 nm; micrometer (micron) mm = 1000 um; millimeter cm = 10 mm; centimeter dm = 100 mm; decameter m = 1000 mm; meter km = 1000 m; kilometer mil = 254000 Ang; mil (1/1000 inch) inch = 1000 mil; inch ft = 12 inch; foot yd = 3 ft; yard fthn = 6 ft; fathom frlg = 660 ft; furlong mi = 5280 ft; mile lg = 3 mi; league end units; 4.2.2. Dữ liệu phức hợp Dữ liệu phức hợp (composite) là dữ liệu tạo thành bằng các tổ hợp các dạng dữ liệu cơ bản trên theo các cách khác nhau. Có hai dạng dữ liệu phức hợp cơ bản là kiểu mảng dữ liệu khi các phần tử dữ liệu trong tổ hợp là đồng nhất và đƣợc sắp thứ tự, dạng thứ hai là dạng bản ghi khi các phần tử có thể có các kiểu dữ liệu khác nhau. Kiểu mảng Kiểu mảng (Array) trong VHDL có các tính chất nhƣ sau: 68
- - Các phần tử của mảng có thể là mọi kiểu trong ngôn ngữ VHDL. - Số lƣợng các chỉ số của mảng (hay số chiều của mảng) có thể nhận mọi giá trị nguyên dƣơng. - Mảng chỉ có một và một chỉ số dùng để truy cập tới phần tử. - Miền biến thiên của chỉ số xác định số phần tử của mảng và hƣớng sắp xếp chỉ số trong của mảng từ cao đến thấp hoặc ngƣợc lại. - Kiểu của chỉ số là kiểu số nguyên hoặc liệt kê. Mảng trong VHDL chia làm hai loại là mảng ràng buộc và mảng không ràng buộc. Mảng ràng buộc là mảng đƣợc khai báo tƣờng minh có kích thƣớc cố định. Cú pháp khai báo của mảng này nhƣ sau: type array_name is array (index_range) of type; Trong đó array_name là tên của mảng, index_range là miền biến thiên xác định của chỉ số nếu mảng là mảng nhiều chiều thì các chiều biến thiên cách nhau dấu ―,‖, ví dụ nhƣ sau: type mem is array (0 to 31, 3 to 0) of std_logic; type word is array (0 to 31) of bit; type data is array (7 downto 0) of word; Đối với mảng khai báo không tƣơng minh thì miền giá trị của chỉ số không đƣợc chỉ ra mà chỉ ra kiểu của chỉ số: type array_name is array (type of index range ) of word; type matrix is array (integer range ) of real; Cách truy cập tới các phần tử của mảng của một mảng n chiều nhƣ sau: array_name (index1, index 2, , indexn) ví dụ: matrix(1,2), mem (3). Kiểu bản ghi Bản ghi (Record) là nhóm của một hoặc nhiều phần tử thuộc những kiểu khác nhau và đƣợc truy cập tới nhƣ một đối tƣợng. Bản ghi có những đặc điểm nhƣ sau: - Mỗi phần tử của bản ghi đƣợc truy cập tới theo trƣờng. - Các phần tử của bản ghi có thể nhận mọi kiểu của ngôn ngữ VHDL kể cả mảng và bản ghi. ví dụ về bản ghi type stuff is record I : integer; 69
- X : real; Day : integer range 1 to 31; name : string(1 to 48); prob : matrix(1 to 3, 1 to 3); end record; Các phần tử của bản ghi đƣợc truy cập theo tên của bản ghi và tên trƣờng ngăn cách nhau bằng dấu ―.‖, ví dụ: node.data; stuff.day 5. Toán tử và biểu thức Trong VHDL có tất cả 7 nhóm toán tử đƣợc phân chia theo mức độ ƣu tiên và trật tự tính toán. Trong bảng sau liệt kê các nhóm toán tử theo trật tự ƣu tiên tăng dần: Bảng 2-2 Các toán tử trong VHDL Toán tử logic and, or, nand, nor, xor Các phép toán quan hệ =, /=, , >= Các phép toán dịch sll, srl, sla, sra, rol, ror Các phép toán cộng, hợp +, -, & Toán tử dấu +, - Các phép toán nhân *, /, mod, rem Các phép toán khác , abs, not Các quy định về trật tự các phép toán trong biểu thức đƣợc thực hiện nhƣ sau: - Trong các biểu thức phép toán có mức độ ƣu tiên lớn hơn sẽ đƣợc thực hiện trƣớc. Các dấu ngoặc đơn ―(―, ―)‖ phân định miền ƣu tiên của từng nhóm biểu thức. - Các phép toán trong nhóm với cùng một mức độ ƣu tiên sẽ đƣợc thực hiện lần lƣợt từ trái qua phải. 5.1. Toán tử logic Các phép toán logic gồm and, or, nand, nor, xor, và not. Các phép toán này tác động lên các đối tƣợng kiểu BIT và Boolean và mảng một chiều kiểu BIT. Đối với các phép toán hai ngôi thì các toán hạng nhất định phải cùng kiểu, nếu hạng tử là mảng BIT một chiều thì phải có cùng độ dài, khi đó các phép toán logic sẽ thực hiện đối với các bit tƣơng ứng của hai toán hạng có cùng chỉ số. 70
- Phép toán not chỉ có một toán hạng, khi thực hiện với mảng BIT một chiều thì sẽ cho kết quả là mảng BIT lấy đảo ở tất cả các vị trí của mảng cũ. Ví dụ: library ieee; use ieee.std_logic_1164.all; entity logic_example is port( in1 : in std_logic_vector (5 downto 0); in2 : in std_logic_vector (5 downto 0); out1 : out std_logic_vector (5 downto 0) ); end entity; architecture rtl of logic_example is begin out1(0) , >= thực hiện các phép toán so sánh giữa các toán tử có cùng kiểu nhƣ Integer, real, character. Và cho kết quả dạng Boolean. Việc so sánh các hạng tử trên cơ sở miền giá trị của các đối tƣợng dữ liệu. Các phép toán quan hệ rất hay đƣợc sử dụng trong các câu lệnh rẽ nhánh Ví dụ đầy đủ về phép toán so sánh thể hiện ở đoạn mã sau: library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity compare_example is port( val1 : in std_logic_vector (7 downto 0); val2 : in std_logic_vector (7 downto 0); res : out std_logic_vector (2 downto 0) ); end entity; 71
- architecture rtl of compare_example is begin compare: process (val1, val2) begin if val1 > val2 then res(0) <= '1'; else res (0) <= '0'; end if; if val1 = val2 then res(1) <= '1'; else res (1) <= '0'; end if; if val1 < val2 then res(2) <= '1'; else res (2) <= '0'; end if; end process compare; end rtl; 5.3. Các phép toán 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; Bảng 2-3 Các phép toán dịch trong VHDL Toán Phép toán Kiểu của sho Kiểu của Kiểu kết tử shv quả sll Dịch trái logic Mảng 1 chiều kiểu BIT Integer Cùng kiểu hoặc BOOLEAN sho srl Dịch phải logic Mảng 1 chiều kiểu BIT Integer Cùng kiểu hoặc BOOLEAN sho sla Dịch trái số học Mảng 1 chiều kiểu BIT Integer Cùng kiểu hoặc BOOLEAN sho sra Dịch phải số học Mảng 1 chiều kiểu BIT Integer Cùng kiểu hoặc BOOLEAN sho rol Dịch vòng tròn Mảng 1 chiều kiểu BIT Integer Cùng kiểu sang trái hoặc BOOLEAN sho ror Dịch vòng tròn Mảng 1 chiều kiểu BIT Integer Cùng kiểu phải hoặc BOOLEAN sho Đối với dịch 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 (LSB) nếu dịch 72
- 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 Giả sử có giá trị sho = ―11000110‖ , shv = 2, xét đoạn mã sau library ieee; USE ieee.Numeric_STD.all; USE ieee.Numeric_BIT.all; library STD; use STD.TEXTIO.ALL; entity shift_example is end entity; architecture rtl of shift_example is signal sho: bit_vector(7 downto 0) := "11000110"; begin shifting: process (sho) variable str:line; begin write(str, string'("sho sll 2 = ")); write(str, sho sll 2); writeline(OUTPUT, str); write(str, string'("sho srl 2 = ")); write(str, sho srl 2); writeline(OUTPUT, str); write(str, string'("sho sla 2 = ")); write(str, sho sla 2); writeline(OUTPUT, str); write(str, string'("sho sra 2 = ")); write(str, sho sra 2); writeline(OUTPUT, str); write(str, string'("sho rol 2 = ")); write(str, sho rol 2); writeline(OUTPUT, str); write(str, string'("sho ror 2 = ")); write(str, sho ror 2); writeline(OUTPUT, str); end process shifting; end architecture; Với đoạn mã trên khi mô phỏng sẽ thu đƣợc kết quả: # sho sll 2 = 00011000 # sho srl 2 = 00110001 # sho sla 2 = 00011000 # sho sra 2 = 11110001 73
- # sho rol 2 = 00011011 # sho ror 2 = 10110001 5.4. Các phép toán cộng trừ và hợp Các phép toán +, - là các phép tính hai ngôi, các phép toán cộng và trừ có cú pháp thông thƣờng, hạng tử của phép toán này là tất cả các kiểu dữ liệu kiểu số gồm INTEGER, REAL. Bảng 2-4 Các phép toán cộng dich và hợp Toán Phép toán Kiểu toán tử trái Kiểu của toán tử Kiểu kết quả tử phải + Phép cộng Dữ liệu kiểu số Cùng kiểu Cùng kiểu - Phép trừ Dữ liệu kiểu số Cùng kiểu Cùng kiểu & Phép hợp Kiểu mảng hoặc phần Kiểu mảng hoặc Kiểu mảng tử mảng phần tử mảng Phép toán hợp (concatennation) & có đối số có thể là mảng hoặc phần tử mảng và kết quả hợp tạo ra một mảng mới có các phần tử ghép bởi các phần tử của các toán tử hợp, các ví dụ dƣới đây sẽ minh họa rõ thêm cho phép hợp library ieee; use ieee.std_logic_1164.all; entity dublicate is port( in1 : in std_logic_vector(3 downto 0); out1 : out std_logic_vector(7 downto 0) ); end entity; architecture rtl of dublicate is begin out1 <= in1 & in1; end rtl; Trong ví dụ trên nếu gán giá trị in1 = ―1100‖ thu đƣợc tƣơng ứng ở đầu ra out1 = ―11001100‖. 5.5. Các phép dấu Các phép toán quan hệ gồm +, -, thực hiện với các giá trị dạng số và trả về giá trị dạng số tƣơng ứng. 74