Giáo trình Ngôn ngữ mô tả phần cứng Verilog

doc 217 trang phuongnguyen 4380
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Ngôn ngữ mô tả phần cứng Verilog", để 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:

  • docgiao_trinh_ngon_ngu_mo_ta_phan_cung_verilog.doc

Nội dung text: Giáo trình Ngôn ngữ mô tả phần cứng Verilog

  1. ĐẠI HỌC QUỐC GIA THÀNH PHỐ HỒ CHÍ MINH TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN oOo Giáo trình NGÔN NGỮ MÔ TẢ PHẦN CỨNG VERILOG Biên soạn: TS. Vũ Đức Lung ThS. Lâm Đức Khải Ks. Phan Đình Duy 2012
  2. Giáo trình ngôn ngữ Verilog HDL Lời nói đầu Ngày nay, khi mạch thiết kế với hàng triệu cổng logic được tích hợp trong một con Chip thì việc thiết kế mạch và đi dây kết nối bằng tay trở nên bất khả thi, chính từ lí do đó một khái niệm ngôn ngữ có mức độ trừu tượng cao dùng để mô tả thiết kế phần cứng được ra đời, đó chính là Verilog. Cùng với sự ra đời của ngôn ngữ mô tả phần cứng Verilog là hàng loạt các công cụ EDA (Electronic Design Automation) và CAD (Computer Aided Design) đã giúp cho những kĩ sư thiết kế phần cứng tạo nên những con Chip có độ tích hợp rất cao, tốc độ siêu việt và chức năng đa dạng. Giáo trình Ngôn ngữ mô tả phần cứng Verilog nhằm giúp sinh viên trang bị kiến thức về thiết kế vi mạch. Giáo trình tập trung vào mảng thiết kế các mạch số với mạch tổ hợp và mạch tuần tự. Giáo trình cũng giới thiệu về các bước cần thực hiện trong quá trình thiết kế vi mạch từ việc mô tả thiết kế, kiểm tra, phân tích cho đến tổng hợp phần cứng của thiết kế. Giáo trình Ngôn ngữ mô tả phần cứng Verilog dùng cho sinh viên chuyên ngành Kĩ thuật máy tính và sinh viên các khối Điện tử. Để tiếp nhận kiến thức dễ dàng, sinh viên cần trang bị trước kiến thức về thiết kế số và hệ thống số. Giáo trình này được biên dịch và tổng hợp từ kinh nghiệm nghiên cứu giảng dạy của tác giả và ba nguồn tài liệu chính:  IEEE Standard for Verilog Hardware Description Language, 2006;  Verilog Digital System Design, Second Edition, McGraw-Hill;  The Complete Verilog Book, Vivek Sagdeo, Sun Micro System, Inc. Nhằm cung cấp một luồng kiến thức mạch lạc, giáo trình được chia ra làm 9 chương: . Chương 1: Dẫn nhập thiết kế hệ thống số với Verilog. Chương này sẽ giới thiệu lịch sử phát triển của ngôn ngữ mô tả phần cứng Verilog, bên cạnh đó một qui trình thiết kế vi mạch sử dụng ngôn ngữ mô tả phần cứng Verilog cũng được trình bày cụ thể ở đây. . Chương 2: Trình bày các từ khóa được sử dụng trong môi trường mô tả thiết kế bởi Verilog. . Chương 3: Trình bày các loại dữ liệu được sử dụng trong thiết kế mạch bởi Verilog, gồm hai loại dữ liệu chính đó là loại dữ liệu net và loại dữ liệu biến. . Chương 4: Trình bày các toán tử cũng như các dạng biểu thức được hỗ trợ bởi Verilog. . Chương 5: Giới thiệu cấu trúc của một thiết kế, phương thức sử dụng thiết kế con. . Chương 6: Trình bày phương pháp thiết kế sử dụng mô hình cấu trúc, trong phương thức [Type text] Page 2
  3. Giáo trình ngôn ngữ Verilog HDL này, module thiết kế được xây dựng bằng cách gọi các module thiết kế nhỏ hơn và kết nối chúng lại. . Chương 7: Trình bày phương thức thiết kế sử dụng mô hình RTL bởi phép gán nối tiếp và mô hình hành vi sử dụng ngôn ngữ có tính trừu tượng cao tương tự như ngôn ngữ lập trình. Phần thiết kế máy trạng thái sử dụng mô hình hành vi cũng được nêu ra trong chương này. . Chương 8: Trình bày phương pháp thiết kế và sử dụng tác vụ và hàm. . Chương 9: Giới thiệu các phương pháp kiểm tra chức năng của thiết kế. Do thời gian cũng như khối lượng trình bày giáo trình không cho phép tác giả đi sâu hơn về mọi khía cạnh của thiết kế vi mạch như phân tích định thời, tổng hợp phần cứng, Để có được những kiến thức này, độc giả có thể tham khảo trong các tài liệu tham khảo mà giáo trình này đã cung cấp. Mặc dù nhóm tác giả đã cố gắng biên soạn kỹ lưỡng tuy nhiên cũng khó tránh khỏi những thiếu sót. Nhóm tác giả mong nhận được những đóng góp mang tính xây dựng từ quý độc giả nhằm chỉnh sửa giáo trình hoàn thiện hơn. Nhóm tác giả [Type text] Page 3
  4. Giáo trình ngôn ngữ Verilog HDL Contents Lời nói đầu 2 1 Chương 1. Dẫn nhập thiết kế hệ thống số với Verilog 10 1.1 Qui trình thiết kế số 10 1.1.1 Dẫn nhập thiết kế 12 1.1.2 Testbench trong Verilog 13 1.1.3 Đánh giá thiết kế 13 1.1.3.1 Mô phỏng 13 1.1.3.2 Kĩ thuật chèn kiểm tra (assertion) 15 1.1.3.3 Kiểm tra thông thường 16 1.1.4 Biên dịch và tổng hợp thiết kế 16 1.1.4.1 Phân tích 17 1.1.4.2 Tạo phần cứng 17 1.1.4.3 Tối ưu logic 17 1.1.4.4 Binding 18 1.1.4.5 Sắp xếp cell và đi dây kết nối 18 1.1.5 Mô phỏng sau khi tổng hợp thiết kế 19 1.1.6 Phân tích thời gian 20 1.1.7 Tạo linh kiện phần cứng 20 1.2 Ngôn ngữ mô tả phần cứng Verilog (Verilog HDL) 20 1.2.1 Quá trình phát triển Verilog 20 1.2.2 Những đặc tính của Verilog 21 1.2.2.1 Mức độ chuyển mạch 21 1.2.2.2 Mức độ cổng 21 1.2.2.3 Độ trì hoãn giữa pin đến pin 22 1.2.2.4 Mô tả Bus 22 1.2.2.5 Mức độ hành vi 22 1.2.2.6 Những tiện ích hệ thống 22 1.2.2.7 PLI 22 1.2.3 Sơ lược về Verilog 22 1.3 Tổng kết 23 1.4 Bài tập 23 2 Chương 2. Qui ước về từ khóa 25 2.1 Khoảng trắng 25 2.2 Chú thích 25 2.3 Toán tử 25 2.4 Số học 25 2.4.1 Hằng số nguyên 26 2.4.2 Hằng số thực 29 2.4.3 Số đảo 30 2.5 Chuỗi 30 2.5.1.1 Khai báo biến chuỗi 30 2.5.1.2 Xử lí chuỗi 30 2.5.1.3 Những kí tự đặc biệt trong chuỗi 31 2.6 Định danh, từ khóa và tên hệ thống 31 2.6.1 Định danh với kí tự “” 32 2.6.2 Tác vụ hệ thống và hàm hệ thống 32 2.7 Bài tập 33 3 Chương 3. Loại dữ liệu trong Verilog 70 3.1 Khái quát 70 [Type text] Page 4
  5. Giáo trình ngôn ngữ Verilog HDL 3.2 Những hệ thống giá trị 70 3.3 Khai báo loại dữ liệu 71 3.3.1 Giới thiệu 71 3.4 Khai báo loại dữ liệu net 72 3.4.1 Giới thiệu 72 3.4.2 Wire và Tri 73 3.4.3 Wired net 75 3.4.3.1 Wand và triand Nets 75 3.4.3.2 Wor và Tri or 76 3.4.4 Tri reg net 76 3.4.5 Tri 0 và Tri 1 Nets 77 3.4.6 Supply0 và Supply1 Nets 77 3.4.7 Thời gian trì hoãn trên net 78 3.5 Khai báo loại dữ liệu biến - reg 79 3.6 Khai báo port 79 3.6.1 Giới thiệu 79 3.6.2 input 79 3.6.3 output 80 3.6.4 inout 80 3.7 Khai báo mảng và phần tử nhớ một và hai chiều. 80 3.7.1 Giới thiệu 80 3.7.2 Mảng net 81 3.7.3 Mảng thanh ghi 81 3.7.4 Mảng phần tử nhớ 82 3.8 Khai báo loại dữ liệu biến 83 3.8.1 Giới thiệu 83 3.8.2 Integer 83 3.8.3 Time 83 3.8.4 Số thực (real) và thời gian thực (realtime) 84 3.9 Khai báo tham số 85 3.9.1 Giới thiệu 85 3.9.2 Tham số module (module parameter) 85 3.9.2.1 Parameter 85 3.9.2.1.1 Giới thiệu 85 3.9.2.1.2 Thay đổi giá trị của tham số khai báo parameter 86 3.9.2.1.2.1 Phát biểu defparam 86 3.9.2.1.2.2 Phép gán giá trị tham số khi gọi instance của module 87 3.9.2.1.3 Sự phụ thuộc tham số 92 3.9.2.2 Tham số cục bộ (local parameter) 92 3.9.3 Tham số đặc tả (specify parameter) 92 3.10 Bài tập 94 4 Chương 4. Toán tử, Toán hạng và Biểu thức 95 4.1 Biểu thức giá trị hằng số 95 4.2 Toán tử 96 4.2.1 Toán tử với toán hạng số thực 96 4.2.2 Toán tử ưu tiên 97 4.2.3 Sử dụng số nguyên trong biểu thức 98 4.2.4 Thứ tự tính toán trong biểu thức 99 4.2.5 Toán tử số học (+, -, *, /, %, , +, -) 99 4.2.6 Biểu thức số học với tập thanh ghi (regs) và số nguyên (integer) 101 4.2.7 Toán tử quan hệ (>, =, <=) 102 [Type text] Page 5
  6. Giáo trình ngôn ngữ Verilog HDL 4.2.8 Toán tử so sánh bằng (==, !=, ===, !==) 103 4.2.9 Toán tử logic (&&, ||, !) 104 4.2.10 Toán tử thao tác trên bit (&, |, ^, ~, ~^, ^~) 104 4.2.11 Toán tử giảm 106 4.2.12 Toán tử dịch (>>, >>, <<<) 107 4.2.13 Toán tử điều kiện (?:) 108 4.2.14 Toán tử ghép nối ({}) và Toán tử lặp ({{}}) 109 4.2.14.1 Toán tử ghép nối {} 109 4.2.14.2 Toán tử lặp {{}} 110 4.3 Toán hạng 111 4.3.1 Vector bit-select và part-select addressing 111 4.3.2 Địa chỉ mảng và phần tử nhớ 112 4.3.3 Chuỗi 114 4.3.3.1 Toán tử chuỗi 114 4.3.3.2 Giá trị chuỗi đệm và vấn đề tiềm ẩn 114 4.3.3.3 Chuỗi rỗng 115 4.4 Biểu thức trì hoãn thời gian tối thiểu, trung bình, và tối đa 115 4.5 Biểu thức độ dài bit 117 4.5.1 Qui luật cho biểu thức độ dài bit 117 4.5.2 Ví dụ minh họa vấn đề về biểu thức độ dài bit 118 4.5.3 Ví dụ minh họa về biểu thức tự xác định 119 4.6 Biểu thức có dấu 120 4.6.1 Qui định cho những loại biểu thức 120 4.6.2 Những bước định giá một biểu thức 121 4.6.3 Những bước định giá một phép gán 122 4.6.4 Tính toán những biểu thức của hai số có dấu X và Z 122 4.7 Những phép gán và phép rút gọn 122 4.8 Bài tập 123 5 Chương 5. Cấu trúc phân cấp và module 124 5.1 Cấu trúc phân cấp 124 5.2 Module 124 5.2.1 Khai báo module 124 5.2.2 Module mức cao nhất 126 5.2.3 Gọi và gán đặc tính một module (instantiate) 126 5.2.4 Khai báo port 129 5.2.4.1 Định nghĩa port 129 5.2.4.2 Liệt kê port 130 5.2.4.3 Khai báo port trong thân module 130 5.2.4.4 Khai báo port đầu module 131 5.2.4.5 Kết nối các port của module được gọi bằng danh sách thứ tự 132 5.2.4.6 Kết nối các port của module được gọi bằng tên 133 5.2.4.7 Số thực trong kết nối port 134 5.2.4.8 Kết nối những port không tương tự nhau 135 5.2.4.9 Những qui định khi kết nối port 135 5.2.4.10 Loại net tạo ra từ việc kết nối port không tương tự nhau 136 5.2.4.11 Kết nối những giá trị có dấu thông qua (port) 137 5.3 Bài tập 137 6 Chương 6. Mô hình thiết kế cấu trúc (Structural model) 138 6.1 Giới thiệu 138 6.2 Những linh kiện cơ bản 138 6.2.1 Cổng and, nand, or, nor, xor, xnor 138 6.2.2 Cổng buf và not 139 [Type text] Page 6
  7. Giáo trình ngôn ngữ Verilog HDL 6.2.3 Cổng ba trạng thái bufif1, bufif0, notif1, và notif0 140 6.2.4 Công tắc MOS 141 6.2.5 Công tắc truyền hai chiều 142 6.2.6 Công tắc CMOS 143 6.2.7 Nguồn pullup và pulldown 144 6.2.8 Mô hình độ mạnh logic 145 6.2.9 Độ mạnh và giá trị của những tín hiệu kết hợp 147 6.2.9.1 Sự kết hợp giữa những tín hiệu có độ mạnh rõ ràng 147 6.2.9.2 Độ mạnh không rõ ràng: nguồn và sự kết hợp 147 6.2.9.3 Tín hiệu có độ mạnh không rõ ràng và tín hiệu có độ mạnh rõ ràng 153 6.2.10 Sự suy giảm độ mạnh bằng những linh kiện không trở 158 6.2.11 Sự suy giảm độ mạnh bằng những linh kiện trở 158 6.2.12 Độ mạnh của loại net 159 6.2.12.1 Độ mạnh của net tri0, tri1 159 6.2.12.2 Độ mạnh của trireg 159 6.2.12.3 Độ mạnh của net supply0, supply1 159 6.2.13 Độ trì hoãn cổng (gate) và net 159 6.2.14 Độ trì hoãn min:typ:max 161 6.2.15 Độ phân rã điện tích của net trireg 162 6.2.15.1 Quá trình phân rã điện tích 162 6.2.15.2 Đặc tả trì hoãn của thời gian phân rã điện tích 163 6.3 Những phần tử cơ bản người dùng tự định nghĩa (UDP) 164 6.3.1 Định nghĩa phần tử cơ bản UDP 164 6.3.1.1 Tiêu đề UDP 166 6.3.1.2 Khai báo cổng (port) UDP 167 6.3.1.3 Khai báo khởi tạo UDP tuần tự 167 6.3.1.4 Bảng khai báo UDP 167 6.3.1.5 Giá trị Z trong UDP 168 6.3.1.6 Tổng hợp các ký hiệu 168 6.3.2 UDP tổ hợp 169 6.3.3 UDP tuần tự tích cực mức 170 6.3.4 UDP tuần tự tích cực cạnh 171 6.3.5 Mạch hỗn hợp giữa UDP mạch tích cực mức và UDP tích cực cạnh 172 6.3.6 Gọi sử dụng UDP 173 6.4 Mô tả mạch tổ hợp và mạch tuần tự sử dụng mô hình cấu trúc 174 6.4.1 Mô tả mạch tổ hợp 174 6.4.2 Mô tả mạch tuần tự 177 6.5 Bài tập 179 7 Chương 7. Mô hình thiết kế hành vi (Behavioral model) 220 7.1 Khái quát 220 7.2 Phép gán nối tiếp hay phép gán liên tục - mô hình thiết kế RTL (continuous assignment) 220 7.2.1 Giới thiệu 220 7.2.2 Phép gán nối tiếp khi khai báo net 220 7.2.3 Phát biểu phép gán nối tiếp tường minh assign 221 7.2.4 Tạo độ trì hoãn (delay) cho phép gán 222 7.2.5 Độ mạnh phép gán 223 7.3 Phép gán qui trình - mô hình thiết kế ở mức độ thuật toán (procedural assignment) 224 7.3.1 Phép gán khai báo biến 227 7.3.2 Phép gán qui trình kín (blocking assignment) '=' 228 7.3.2.1 Mạch tổ hợp với phép gán qui trình kín 228 7.3.3 Phép gán qui trình hở (non-blocking assignment) 229 [Type text] Page 7
  8. Giáo trình ngôn ngữ Verilog HDL 7.3.3.1 Mạch tuần tự với phép gán qui trình hở 233 7.4 Phát biểu có điều kiện 234 7.4.1 Cấu trúc if-else-if 235 7.5 Phát biểu Case 237 7.5.1 Phát biểu Case với “don’t care” 239 7.5.2 Phát biểu case với biểu thức hằng số 240 7.6 Phát biểu vòng lặp 241 7.6.1 Các phát biểu lặp 241 7.6.2 Cú pháp 242 7.7 Điều khiển định thời (procedural timing controls) 244 7.7.1Điều khiển trì hoãn (delay control) 244 7.7.2Điều khiển sự kiện (event control) 245 7.7.3 Phát biểu “wait” 246 7.8 Phát biểu khối 248 7.8.1 Khối tuần tự 248 7.8.2 Khối song song (fork-join) 249 7.8.3 Tên khối 250 7.9 Cấu trúc qui trình 250 7.9.1 Cấu trúc initial 251 7.9.2 Cấu trúc always 251 7.10 Máy trạng thái (state machine) 252 7.10.1 Máy trạng thái Moore 252 7.10.2 Máy trạng thái Mealy 255 7.11 Bài tập 258 8 Chương 8. Tác vụ (task) và hàm (function) 263 8.1 Phân biệt giữa tác vụ (task) và hàm (function) 263 8.2 Tác vụ và kích hoạt tác vụ 264 8.2.1 Định nghĩa task 264 8.2.2 Khai báo task 265 8.2.3 Kích hoạt tác vụ và truyền đối số 266 8.2.4 Sử dụng bộ nhớ tác vụ và sự kích hoạt đồng thời 270 8.3 Hàm và việc gọi hàm 270 8.3.1 Khai báo hàm 270 8.3.2 Trả về một giá trị từ hàm 273 8.3.3 Việc gọi hàm 273 8.3.4 Những qui tắc về hàm 273 8.3.5 Sử dụng những hàm hằng số 275 8.4 Bài tập 276 9 Chương 9. Kiểm tra thiết kế 277 9.1 Testbench 277 9.1.1 Kiểm tra mạch tổ hợp 278 9.1.2 Kiểm tra mạch tuần tự 280 9.2 Kĩ thuật tạo testbench 281 9.2.1 Dữ liệu kiểm tra 282 9.2.2Điều khiển mô phỏng 282 9.2.3 Thiết lập giới hạn dữ liệu 283 9.2.4 Cung cấp dữ liệu đồng bộ 284 9.2.5 Tương tác testbench 285 9.2.6 Tạo những khoảng thời gian ngẫu nhiên 287 9.2.6.1.1 end 287 9.3 Kiểm tra thiết kế 288 [Type text] Page 8
  9. Giáo trình ngôn ngữ Verilog HDL 9.4 Kĩ thuật chèn (assertion) dùng để kiểm tra thiết kế 289 9.4.1 Lợi ích của kỹ thuật chèn kiểm tra 289 9.4.2 Thư viện thiết kế mở (OVL) 290 9.4.3 Sử dụng kỹ thuật chèn giám sát. 291 9.5 Bài tập 293 [Type text] Page 9
  10. Giáo trình ngôn ngữ Verilog HDL 1 Chương 1. Dẫn nhập thiết kế hệ thống số với Verilog Khi kích thước và độ phức tạp của hệ thống thiết kế ngày càng tăng, nhiều công cụ hỗ trợ thiết kế trên máy tính (CAD) được sử dụng vào quá trình thiết kế phần cứng. Thời kì đầu, những công cụ mô phỏng và tạo ra phần cứng đã đưa ra phương pháp thiết kế, kiểm tra, phân tích, tổng hợp và tự động tạo ra phần cứng một cách phức tạp. Sự phát triển không ngừng của những công cụ thiết kế một cách tự động là do sự phát triển của những ngôn ngữ mô tả phần cứng (HDLs) và những phương pháp thiết kế dựa trên những ngôn ngữ này. Dựa trên những ngôn ngữ mô tả phần cứng (HDLs), những công cụ CAD trong thiết kế hệ thống số được phát triển và được những kĩ sư thiết kế phần cứng sử dụng rộng rãi. Hiện tại, người ta vẫn đang tiếp tục nghiên cứu để tìm ra những ngôn ngữ mô tả phần cứng tốt hơn. Một trong những ngôn ngữ mô tả phần cứng được sử dụng rộng rãi nhất đó là ngôn ngữ Verilog HDL. Do được chấp nhận rộng rãi trong ngành công nghiệp thiết kế số, Verilog đã trở thành một kiến thức được đòi hỏi phải biết đối với những kĩ sư cũng như sinh viên làm việc và học tập trong lĩnh vực phần cứng máy tính. Chương này sẽ trình bày những công cụ và môi trường làm việc có sẵn tương thích với ngôn ngữ Verilog mà một kĩ sư thiết kế có thể sử dụng trong qui trình thiết kế tự động của mình để giúp đẩy nhanh tiến độ thiết kế. Đầu tiên sẽ trình bày từng bước về thiết kế phân cấp, thiết kế mức cao từ việc mô tả thiết kế bằng ngôn ngữ Verilog đến việc tạo ra phần cứng của thiết kế đó. Những qui trình và những từ khóa chuyên môn cũng sẽ được minh họa ở phần này. Kế tiếp sẽ thảo luận những công cụ CAD hiện có tương thích với Verilog và chức năng của nó trong môi trường thiết kế tự động. Phần cuối cùng của chương này sẽ nói về một số đặc tính của Verilog khiến nó trở thành một ngôn ngữ được nhiều kĩ sư thiết kế phần cứng lựa chọn. 1.1 Qui trình thiết kế số Trong thiết kế một hệ thống số sử dụng môi trường thiết kế tự động, qui trình thiết kế bắt đầu bằng việc mô tả thiết kế tại nhiều mức độ trừu tượng khác nhau và kết thúc bằng việc tạo ra danh sách các linh kiện cũng như các đường kết nối giữa các linh kiện với nhau (netlist) cho một mạch tích hợp với ứng dụng cụ thể (ASIC), mạch in (layout) cho một mạch tích hợp theo yêu cầu khách hàng (custom IC), hoặc một chương trình cho một thiết bị logic có khả năng lập trình được (PLD). Hình 1.1 mô tả từng bước trong qui trình thiết kế này. Bước đầu của thiết kế, một thiết kế sẽ được mô tả bởi sự hỗn hợp giữa mô tả ở mức độ hành vi (behavioural) Verilog, sử dụng những gói (module) thiết kế Verilog đã được thiết kế sẵn, và việc gán hệ thống các bus và wire để liên kết các gói thiết kế này thành một hệ thống [Type text] Page 10
  11. Giáo trình ngôn ngữ Verilog HDL hoàn chỉnh. Kĩ sư thiết kế cũng phải có trách nhiệm tạo ra dữ liệu để kiểm tra (testbench) xem thiết kế đúng chức năng hay chưa cũng như dùng để kiểm tra thiết kế sau khi tổng hợp. Việc kiểm tra thiết kế có thể thực hiện được bằng việc mô phỏng, chèn những kĩ thuật kiểm tra, kiểm tra thông thường hoặc kết hợp cả ba phương pháp trên. Sau bước kiểm tra đánh giá thiết kế (bước này được gọi là kiểm tra tiền tổng hợp (presynthesis verification)), thiết kế sẽ được tiếp tục bằng việc tổng hợp để tạo ra phần cứng thực sự cho hệ thống thiết kế cuối cùng (ASIC, custom IC hay FPLD, ). Nếu hệ thống thiết kế là ASIC, thiết kế sẽ sẽ được sản xuất bởi nhà sản xuất khác; nếu là custom IC, thiết kế sẽ được sản xuất trực tiếp; nếu là FPLD, thiết kế sẽ được nạp lên thiết bị lập trình được. Hình 1.1 Luồng thiết kế ASIC Sau bước tổng hợp và trước khi phần cứng thực sự được tạo ra, một quá trình mô phỏng khác (hậu tổng hợp (postsynthesis)) phải được thực hiện. Việc mô phỏng này, ta có thể sử dụng testbench tương tự testbench đã sử dụng trong mô phỏng tiền tổng hợp (presynthesis). [Type text] Page 11
  12. Giáo trình ngôn ngữ Verilog HDL Bằng phương pháp này, mô hình thiết kế ở mức độ hành vi và mô hình phần cứng của thiết kế được kiểm tra với cùng dữ liệu ngõ vào. Sự khác nhau giữa mô phỏng tiền tổng hợp và hậu tổng hợp đó là mức độ chi tiết có thể đạt được từ mỗi loại mô phỏng. Những phần tiếp theo sẽ mô tả tỉ mỉ về mỗi khối trong Hình 1.1. 1.1.1 Dẫn nhập thiết kế Bước đầu tiên trong thiết kế hệ thống số là bước dẫn nhập thiết kế. Trong bước này, thiết kế được mô tả bằng Verilog theo phong cách phân cấp từ cao xuống thấp (top-down). Một thiết kế hoàn chỉnh có thể bao gồm những linh kiện ở mức cổng hoặc mức transistor, những khối (module) phần cứng có chức năng phức tạp hơn được mô tả ở mức độ hành vi, hoặc những linh kiện được liệt kê bởi cấu trúc bus. Do những thiết kế Verilog ở mức cao thường được mô tả ở mức độ mà tại đó, nó mô tả hệ thống những thanh ghi và sự truyền dữ liệu giữa những thanh ghi này thông qua hệ thống bus, vì vậy, việc mô tả hệ thống thiết kế ở mức độ này được xem như là mức độ truyền dữ liệu giữa các thanh ghi (RTL - Register Transfer Level). Một thiết kế hoàn chỉnh được mô tả như vậy sẽ tạo ra được phần cứng tương ứng thực sự rõ ràng. Những cấu trúc thiết kế Verilog ở mức độ RTL sử dụng những phát biểu qui trình (producedural statements), phép gán liên tục (continuous assignments), và những phát biểu gọi sử dụng các khối (module) đã xây dựng sẵn. Những phát biểu qui trình Verilog (procedural statements) được dùng để mô tả mức độ hành vi ở mức cao. Một hệ thống hoặc một linh kiện được mô tả ở mức độ hành vi thì tương tự với việc mô tả trong ngôn ngữ phần mềm. Ví dụ, chúng ta có thể mô tả một linh kiện bằng việc kiểm tra điều kiện ngõ vào của nó, bật cờ hiệu, chờ cho đến khi có sự kiện nào đó xảy ra, quan sát những tín hiệu bắt tay và tạo ra ngõ ra. Mô tả hệ thống một cách qui trình như vậy, cấu trúc if-else, case của Verilog cũng như những ngôn ngữ phần mềm khác đều sử dụng như nhau. Những phép gán liên tục (continuous assignment) trong Verilog là những phép gán cho việc thể hiện chức năng những khối logic, những phép gán bus, hoặc mô tả việc kết nối giữa hệ thống bus và các chân ngõ vào, ngõ ra. Kết hợp với những hàm Boolean và những biểu thức có điều kiện, những cấu trúc ngôn ngữ này có thể được dùng để mô tả những linh kiện và hệ thống theo những phép gán thanh ghi và bus của chúng. Những phát biểu gọi sử dụng khối Verilog đã được thiết kế sẵn (instantiantion statements) được dùng cho những linh kiện mức thấp trong một thiết kế ở mức độ cao hơn. Thay vì mô tả ở mức độ hành vi, chức năng, hoặc bus của một hệ thống, chúng ta có thể mô tả một hệ thống bằng Verilog bằng cách kết nối những linh kiện ở mức độ thấp hơn. Những linh kiện này có thể nhỏ như là mức cổng hay transistor, hoặc có thể lớn như là một bộ vi xử lí hoàn chỉnh. [Type text] Page 12
  13. Giáo trình ngôn ngữ Verilog HDL 1.1.2 Testbench trong Verilog Một hệ thống được thiết kế dùng Verilog phải được mô phỏng và kiểm tra xem thiết kế đã đúng chức năng hay chưa trước khi tạo ra phần cứng. Trong quá trình này, những lỗi thiết kế và sự không tương thích giữa những linh kiện dùng trong thiết kế có thể được phát hiện. Việc chạy mô phỏng và kiểm tra một thiết kế đòi hỏi phải tạo ra một dữ liệu ngõ vào kiểm tra và quá trình quan sát kết quả sau khi chạy mô phỏng, dữ liệu dùng để kiểm tra này được gọi là testbench. Một testbench sử dụng cấu trúc mức cao của Verilog để tạo ra dữ liệu kiểm tra, quan sát đáp ứng ngõ ra, và cả việc kết nối giữa những tín hiệu trong thiết kế. Bên trong testbench, hệ thống thiết kế cần chạy mô phỏng sẽ được gọi ra (instantiate) trong testbench. Dữ liệu testbench cùng với hệ thống thiết kế sẽ tạo ra một mô hình mô phỏng mà sẽ được sử dụng bởi một công cụ mô phỏng Verilog. 1.1.3 Đánh giá thiết kế Một nhiêm vụ quan trọng trong bất kì thiết kế số nào cũng cần đó là đánh giá thiết kế. Đánh giá thiết kế là quá trình mà người thiết kế sẽ kiểm tra thiết kế của họ có sai sót nào có thể xảy ra trong suốt quá trình thiết kế hay không. Một sai sót thiết kế có thể xảy ra do sự mô tả thiết kế mơ hồ, do sai sót của người thiết kế, hoặc sử dụng không đúng những khối trong thiết kế. Đánh giá thiết kế có thể thực hiện bằng mô phỏng, bằng việc chèn những kĩ thuật kiểm tra, hoặc kiểm tra thông thường. 1.1.3.1 Mô phỏng Chạy mô phỏng dùng trong việc đánh giá thiết kế, được thực hiện trước khi thiết kế được tổng hợp. Bước chạy mô phỏng này được hiểu như mô phỏng ở mức độ hành vi, mức độ RTL hay tiền tổng hợp. Ở mức độ RTL, một thiết kế bao gồm xung thời gian clock nhưng không bao gồm trì hoãn thời gian trên cổng và dây kết nối (wire). Chạy mô phỏng ở mức độ này sẽ chính xác theo xung clock. Thời gian của việc chạy mô phỏng ở mức độ RTL là theo tín hiệu xung clock, không quan tâm đến những vấn đề như: nguy hiểm tiềm ẩn có thể khiến thiết kế bị lỗi (hazards, glitch), hiện tượng chạy đua không kiểm soát giữa những tín hiệu (race conditions), những vi phạm về thời gian setup và hold của tín hiệu ngõ vào, và những vấn đề liên quan đến định thời khác. Ưu điểm của việc mô phỏng này là tốc độ chạy mô phỏng nhanh so với chạy mô phỏng ở mức cổng hoặc mức transistor. Chạy mô phỏng cho một thiết kế đòi hỏi dữ liệu kiểm tra. Thông thường trong môi trường mô phỏng Verilog sẽ cung cấp nhiều phương pháp khác nhau để đưa dữ liệu kiểm tra này vào thiết kế để kiểm tra. Dữ liệu kiểm tra có thể được tạo ra bằng đồ họa, sử dụng những công cụ soạn thảo dạng sóng, hoặc bằng testbench. Hình 1.2 mô tả hai cách khác nhau để định [Type text] Page 13
  14. Giáo trình ngôn ngữ Verilog HDL nghĩa dữ liệu kiểm tra ngõ vào của một công cụ mô phỏng. Những ngõ ra của công cụ mô phỏng là những dạng sóng ngõ ra (có thể quan sát trực quan). Hình 1.2. Hai cách khác nhau để định nghĩa dữ liệu kiểm tra ngõ vào Để chạy mô phỏng với Verilog testbench, trong testbench sẽ gọi hệ thống thiết kế ra để kiểm tra, lúc này hệ thống thiết kế được xem như là một phần của testbench, testbench sẽ cung cấp dữ liệu kiểm tra đến ngõ vào của hệ thống thiết kế. Hình 1.3 mô tả một đoạn code của một mạch đếm, testbench của nó, cũng như kết quả chạy mô phỏng của nó dưới dạng sóng ngõ ra. Quan sát hình ta thấy việc chạy mô phỏng sẽ đánh giá chức năng của mạch đếm. Với mỗi xung clock thì ngõ ra bộ đếm sẽ tăng lên 1. Chú ý rằng, theo biểu đồ thời gian thì ngõ ra bộ đếm thay đổi tại cạnh lên xung clock và không có thời gian trì hoãn do cổng cũng như trì hoãn trên đường truyền. Kết quả chạy mô phỏng cho thấy chức năng của mạch đếm là chính xác mà không cần quan tâm đến tần số xung clock. Hiển nhiên, những linh kiện phần cứng thực sự sẽ có đáp ứng khác nhau. Dựa trên định thời và thời gian trì hoãn của những khối được sử dụng, thời gian từ cạnh lên xung clock đến ngõ ra của bộ đếm sẽ có độ trì hoãn khác không. Hơn nữa, nếu tần số xung clock được cấp vào mạch thực sự quá nhanh so với tốc độ truyến tín hiệu bên trong các cổng và transistor của thiết kế thì ngõ ra của thiết kế sẽ không thể biết được. Việc mô phỏng này không cung cấp chi tiết về các vấn đề định thời của hệ thống thiết kế được mô phỏng. Do đó, những vấn đề tiềm ẩn về định thời của phần cứng do trì hoãn trên cổng sẽ không thể phát hiện được. Đây là vấn đề điển hình của quá trỉnh mô phỏng tiền tổng hợp hoặc mô phỏng ở mức độ hành vi. Điều biết được trong Hình 1.3 đó là bộ đếm của ta đếm số nhị phân. Thiết kế hoạt động nhanh chậm thế nào, hoạt đông được ở tần số nào chỉ có thể biết được bằng việc kiểm tra thiết kế sau tổng hợp. [Type text] Page 14
  15. Giáo trình ngôn ngữ Verilog HDL Hình 1.3. Mô tả một đoạn code của một mạch flip-flop 1.1.3.2 Kĩ thuật chèn kiểm tra (assertion) Thay vì phải dò theo kết quả mô phỏng bằng mắt hay tạo những dữ liệu kiểm tra testbench phức tạp, kĩ thuật chèn thiết bị giám sát có thể được sử dụng để kiểm tra tuần tự những đặc tính của thiết kế trong suốt quá trình mô phỏng. Thiết bị giám sát được đặt bên trong hệ thống thiết kế, được mô phỏng bởi người thiết kế. Người thiết kế sẽ quyết định xem chức năng của thiết kế đúng hay sai, những điều kiện nào thiết kế cần phải thỏa mãn. Những điều kiện này phải tuân theo những đặc tính thiết kế, và thiết bị giám sát được chèn vào hệ thống thiết kế để đảm bảo những đặc tính này không bị vi phạm. Chuỗi thiết bị giám sát này sẽ sai nếu một đặc tính nào đó được đặt vào bởi người thiết kế bị vi phạm. Nó sẽ cảnh báo cho người thiết kế rằng thiết kế đã không đúng chức năng như mong đợi. Thư viện OVL (Open Verification Library) cung cấp một chuỗi những thiết bị giám sát để chèn vào hệ thống thiết kế để giám sát những đặc tính thông thường của thiết kế. Người thiết kế có thể dùng những kĩ thuật giám sát của riêng mình để chèn vào thiết kế và dùng chúng kết hợp với testbench trong việc kiểm tra đánh giá thiết kế. [Type text] Page 15
  16. Giáo trình ngôn ngữ Verilog HDL 1.1.3.3 Kiểm tra thông thường Kiểm tra thông thường là quá trình kiểm tra những đặc tính bất kì của thiết kế. Khi một thiết kế hoàn thành, người thiết kế sẽ xây dựng một chuỗi những đặc tính tương ứng với hành vi của thiết kế. Công cụ kiểm tra thông thường sẽ kiểm tra thiết kế để đảm bảo rằng những đặc tính được mô tả đáp ứng được tất cả những điều kiện. Nếu có một đặc tính được phát hiện là không đáp ứng đúng, đặc tính đó được xem như vi phạm. Đặc tính độ bao phủ (coverage) chỉ ra bao nhiêu phần trăm đặc tính của thiết kế đã được kiểm tra. 1.1.4 Biên dịch và tổng hợp thiết kế Tổng hợp là quá trình tạo ra phần cứng tự động từ một mô tả thiết kế phần cứng tương ứng rõ ràng. Một mô tả phần cứng Verilog dùng để tổng hợp không thể bao gồm tín hiệu và mô tả định thời ở mức cổng, hoặc những cấu trúc ngôn ngữ khác mà không dịch sang những phương trình logic tuần tự hoặc tổ hợp. Hơn thế nữa, những mô tả phần cứng Verilog dùng cho tổng hợp phải tuân theo những phong cách viết code một cách nhất định cho mạch tổ hợp cũng như mạch tuần tự. Những phong cách này và cấu trúc Verilog tương ứng của chúng được định nghĩa trong việc tổng hợp RTL. Trong qui trình thiết kế, sau khi một thiết kế được mô tả hoàn thành và kết quả mô phỏng tiền tổng hợp của nó được kiểm tra bởi người thiết kế, nó phải được biên dịch để tiến gần hơn đến việc tạo thành phần cứng thực sự trên silicon. Bước thiết kế này đòi hỏi việc mô tả phần cứng của thiết kế phải được chỉ ra, nghĩa là chúng ta phải chỉ đến một ASIC cụ thể, hoặc một FPGA cụ thể như là thiết bị phần cứng mục đích của thiết kế. Khi thiết bị mục đích được chỉ ra, những tập tin mô tả về công nghệ (technology files) của phần cứng (ASIC, FPGA, hoặc custom IC) sẽ cung cấp chi tiết những thông tin về định thời và mô tả chức năng cho quá trình biên dịch. Quá trình biên dịch sẽ chuyển đổi những phần khác nhau của thiết kế ra một định dạng trung gian (bước phân tích), kết nối tất cả các phần lại với nhau, tạo ra mức logic tương ứng (bước tổng hợp), sắp xếp và kết nối (place and route) những linh kiện trong thiết bị phần cứng mục đích lại với nhau để thực hiên chức năng như thiết kế mong muốn và tạo ra thông tin chi tiết về định thời trong thiết kế. Hình 1.4 mô tả quá trình biên dịch và mô tả hình ảnh kết quả ngõ ra của mỗi bước biên dịch. Như trên hình, ngõ vào của bước này là một mô tả phần cứng bao gồm những mức độ mô tả khác nhau của Verilog, và kết quả ngõ ra của nó là một phần cứng chi tiết cho thiết bị phần cứng mục đích như FPLD hay để sản xuất chip ASIC. [Type text] Page 16
  17. Giáo trình ngôn ngữ Verilog HDL Hình 1.4. Mô tả quá trình biên dịch và mô tả hình ảnh kết quả ngõ ra 1.1.4.1 Phân tích Một thiết kế hoàn chỉnh được mô tả dùng Verilog có thể bao gồm mô tả ở nhiều mức độ khác nhau như mức độ hành vi, hệ thống bus và dây kết nối với những linh kiện Verilog khác. Trước khi một thiết kế hoàn chỉnh tạo ra phần cứng, thiết kế phải được phân tích và tạo ra một định dạng đồng nhất cho tất cả các phần trong thiết kế. Bước này cũng kiểm tra cú pháp và ngữ nghĩa của mã ngõ vào Verilog. 1.1.4.2 Tạo phần cứng Sau khi tạo được một dữ liệu thiết kế có định dạng đồng nhất cho tất cả các linh kiện trong thiết kế, bước tổng hợp sẽ bắt đầu bằng chuyển đổi dữ liệu thiết kế trên sang những định dạng phần cứng thông thường như một chuỗi những biểu thức Boolean hay một netlist những cổng cơ bản. 1.1.4.3 Tối ưu logic Bước kế tiếp của quá trình tổng hợp, sau khi một thiết kế được chuyển đổi sang một chuỗi những biểu thức Boolean, bước tối ưu logic được thực hiện. Bước này nhằm mục đích làm giảm những biểu thức với ngõ vào không đổi, loại bỏ những biểu thức lặp lại, tối thiểu hai mức, tối thiểu nhiều mức. Đây là quá trình tính toán rất hao tốn thời gian và công sức, một số công cụ cho phép người thiết kế quyết định mức độ tối ưu. Kết quả ngõ ra của bước này cũng dưới dạng những biểu thức Boolean, mô tả logic dưới dạng bảng, hoặc netlist gồm những cổng cơ bản. [Type text] Page 17
  18. Giáo trình ngôn ngữ Verilog HDL 1.1.4.4 Binding Sau bước tối ưu logic, quá trình tổng hợp sử dụng thông tin từ thiết bị phần cứng mục đích để quyết định chính xác linh kiện logic nào và thiết bị nào cần để hiện thực mạch thiết kế. Quá trình này được gọi là binding và kết quả ngõ ra của nó được chỉ định cụ thể sử dụng cho FPLD, ASIC, hay custom IC. 1.1.4.5 Sắp xếp cell và đi dây kết nối Bước sắp xếp và đi dây kết nối sẽ quyết định việc đặt vị trí của các linh kiện trên thiết bị phần cứng mục đích. Việc kết nối các ngõ vào và ngõ ra của những linh kiện này dùng hệ thống dây liên kết và vùng chuyển mạch trên thiết bị phần cứng mục đích, được quyết định bởi bước sắp xếp cell và đi dây kết nối này. Kết quả ngõ ra của bước này được đưa tới thiết bị phần cứng mục đích, như nạp lên FPLD, hay dùng để sản xuất ASIC. Một ví dụ minh họa về quá trình tổng hợp được chỉ ra trên Hình 1.5. Trong hình này, mạch đếm đã được dùng chạy mô phỏng trong Hình 1 . 3 được tổng hợp. Ngoài việc mô tả phần cứng thiết kế dùng Verilog, công cụ tổng hợp đòi hỏi những thông tin mô tả thiết bị phần cứng mục đích để tiến hành quá trình tổng hợp của mình. Kết quả ngõ ra của công cụ tổng hợp là danh sách các cổng, các flip-flop có sẵn trong thiết bị phần cứng đích và hệ thống dây kết nối giữa chúng. Hình 1.5 cũng chỉ ra một kết quả ngõ ra mang tính trực quan đã được tạo ra tự động bằng công cụ tổng hợp của Altera Quartus II. [Type text] Page 18
  19. Giáo trình ngôn ngữ Verilog HDL Hình 1.5. Minh họa về quá trình tổng hợp 1.1.5 Mô phỏng sau khi tổng hợp thiết kế Sau khi quá trình tổng hợp hoàn thành, công cụ tổng hợp sẽ tạo ra một netlist hoàn chỉnh chứa những linh kiện của thiết bị phần cứng đích và các giá trị định thời của nó. Những thông tin chi tiết về các cổng được dùng để hiện thực thiết kế cũng được mô tả trong netlist này. Netlist này cũng bao gồm những thông tin về độ trì hoãn trên đường dây và những tác động của tải lên các cổng dùng trong quá trình hậu tổng hợp. Có nhiều định dạng netlist ngõ ra có thể được tạo ra bao gồm cả định dạng Verilog. Một netlist như vậy có thể được dùng để mô phỏng, và mô phỏng này được gọi là mô phỏng hậu tổng hợp. Những vấn đề về định thời, về tần số xung clock, về hiện tượng chạy đua không kiểm soát, những nguy hiểm tiềm ẩn của thiết kế chỉ có thể kiểm tra bằng mô phỏng hậu tổng hợp thực hiện sau khi thiết kế được tổng hợp. Như trên Hình 1.1, ta có thể sử dụng dữ liệu kiểm tra mà đã dùng cho quá trình mô phỏng tiền tổng hợp để dùng cho quá trình mô phỏng hậu tổng hợp. Do độ trì hoãn trên đường dây và các cổng, đáp ứng của thiết kế sau khi chạy mô phỏng hậu tổng hợp sẽ khác với đáp ứng của thiết kế mà người thiết kế mong muốn. Trong trường hợp này, người thiết kế phải sửa lại thiết kế và cố gắng tránh những sai sót về định thời và hiện tượng chạy đua giữa những tín hiệu không thể kiểm soát. [Type text] Page 19
  20. Giáo trình ngôn ngữ Verilog HDL 1.1.6 Phân tích thời gian Quan sát trên Hình 1.1, bước phân tích thời gian là một phần trong quá trình biên dịch, hoặc trong một số công cụ thì bước phân tích thời gian này được thực hiện sau quá trình biên dịch. Bước này sẽ tạo ra khả năng xấu nhất về độ trì hoãn, tốc độ xung clock, độ trì hoãn từ cổng này đến cổng khác, cũng như thời gian cho việc thiết lập và giữ tín hiệu. Kết quả của bước phân tích thời gian được thể hiện dưới dạng bảng hoặc biểu đồ. Người thiết kế sử dụng những thông tin này để xác định tốc độ xung clock, hay nói cách khác là xác định tốc độ hoạt động của mạch thiết kế. 1.1.7 Tạo linh kiện phần cứng Bước cuối cùng trong qui trình thiết kế tự động dựa trên Verilog đó là tạo ra phần cứng thực sự cho thiết kế. Bước này có thể tạo ra một netlist dùng để sản xuất ASIC, một chương trình để nạp vào FPLD, hay một mạch in cho mạch IC. 1.2 Ngôn ngữ mô tả phần cứng Verilog (Verilog HDL) Trong phần trước, ta đã trình bày từng bước thiết kế ở mức độ RTL từ một mô tả thiết kế Verilog cho đến việc hiện thực ra một phần cứng thực sự. Qui trình thiết kế này chỉ có thể thực hiện được khi ngôn ngữ Verilog có thể hiểu được bởi người thiết kế hệ thống, người thiết kế ở mức độ RTL, người kiểm tra, công cụ mô phỏng, công cụ tổng hợp, và các máy móc liên quan. Bởi vì tầm quan trọng của nó trong qui trình thiết kế, Verilog đã trở thành một chuẩn quốc tế IEEE. Chuẩn này được sử dụng bởi người thiết kế cũng như người xây dựng công cụ thiết kế. 1.2.1 Quá trình phát triển Verilog Verilog được ra đời vào đầu năm 1984 bởi Gateway Design Automation. Khởi đầu, ngôn ngữ đầu tiên được dùng như là một công cụ mô phỏng và kiểm tra. Sau thời gian đầu, ngôn ngữ này được chấp nhận bởi ngành công nghiệp điện tử, bởi các công cụ mô phỏng và công cụ phân tích thời gian, sau này vào năm 1987, công cụ tổng hợp đã được xây dựng và phát triển dựa vào ngôn ngữ này. Gateway Design Automation và những công cụ dựa trên Verilog của hãng sau này được mua bởi Cadence Design System. Từ sau đó, Cadence đóng vai trò hết sức quan trọng trong việc phát triển cũng như phổ biến ngôn ngữ mô tả phần cứng Verilog. Vào năm 1987, một ngôn ngữ mô tả phần cứng khác là VHDL trở thành một chuẩn ngôn ngữ mô tả phần cứng của IEEE. Bởi do sự hỗ trợ của Bộ quốc phòng (DoD), VHDL được sử dụng nhiều trong những dự án lớn của chính phủ Mỹ. Trong nỗ lực phổ biến Verilog, vào năm 1990, OVI (Open Verilog International) được thành lập và nhờ đó, Verilog chiếm ưu thế trong lĩnh vực công nghiệp. Điều này đã tạo ra một sự quan tâm khá lớn từ người dùng và các nhà cung cấp EDA (Electronic Design Automation) tới Verilog. [Type text] Page 20
  21. Giáo trình ngôn ngữ Verilog HDL Vào năm 1993, những nỗ lực nhằm chuẩn hóa ngôn ngữ Verilog được bắt đầu. Verilog trở thành chuẩn IEEE, IEEE Std 1364-1995 vào năm 1995. Với những công cụ mô phỏng, công cụ tổng hợp, công cụ phân tích thời gian, và những công cụ thiết kế dựa trên Verilog đã có sẵn, chuẩn Verilog IEEE này nhanh chóng được chấp nhận sâu rộng trong cộng đồng thiết kế điện tử. Một phiên bản mới của Verilog được chấp nhận bởi IEEE vào năm 2001. Phiên bản mới này được xem như chuẩn Verilog-2001 và được dùng bởi hầu hết người sử dụng cũng như người phát triển công cụ. Những đặc điểm mới trong phiên bản mới đó là nó cho phép bên ngoài có khả năng đọc và ghi dữ liệu, quản lí thư viện, xây dựng cấu hình thiết kế, hỗ trợ những cấu trúc có mức độ trừu tượng cao hơn, những cấu trúc mô tả sự lặp lại, cũng như thêm một số đặc tính vào phiên bản này. Quá trình cải tiến chuẩn này vẫn đang được tiếp tục với sự tài trợ của IEEE. 1.2.2 Những đặc tính của Verilog Verilog là một ngôn ngữ mô tả phần cứng dùng để đặc tả phần cứng từ mức transistor đến mức hành vi. Ngôn ngữ này hỗ trợ những cấu trúc định thời cho việc mô phỏng định thời ở mức độ chuyển mạch và tức thời, nó cũng có khả năng mô tả phần cứng tại mức độ thuật toán trừu tượng. Một mô tả thiết kế Verilog có thể bao gồm sự trộn lẫn giữa những khối (module) có mức độ trừu tượng khác nhau với sự khác nhau về mức độ chi tiết. 1.2.2.1 Mức độ chuyển mạch Những đặc điểm của ngôn ngữ này khiến nó trở nên lí tưởng trong việc mô hình hóa và mô phỏng ở mức độ chuyển mạch, bao gồm khả năng chuyển mạch một chiều cũng như hai chiều, với những thông số về độ trì hoãn và lưu trữ điện tích. Những trì hoãn mạch điện có thể được mô hình hóa như là trì hoãn đường truyền, trì hoãn từ thấp lên cao hay từ cao xuống thấp. Đặc điểm lưu trữ điện tích ở mức độ trừu tượng trong Verilog khiến nó có khả năng mô tả những mạch điện với linh kiện động như là CMOS hay MOS. 1.2.2.2 Mức độ cổng Những cổng cơ bản với những thông số được định nghĩa trước sẽ cung cấp một khả năng thuận tiện trong việc thể hiện netlist và mô phỏng ở mức cổng. Đối với việc mô phỏng mức cổng với mục đích chi tiết và đặc biệt, những linh kiện cổng có thể được định nghĩa ở mức độ hành vi. Verilog cũng cung cấp những công cụ cho việc định nghĩa những phần tử cơ bản với những chức năng đặc biệt. Một hệ thống số logic 4 giá trị đơn giản (0,1,x,z) được sử dụng trong Verilog để thể hiện giá trị cho tín hiệu. Tuy nhiên, để mô hình mức logic chính xác hơn, những tín hiệu Verilog gồm 16 mức giá trị về độ mạnh được thêm vào 4 giá trị đơn giản ở trên. [Type text] Page 21
  22. Giáo trình ngôn ngữ Verilog HDL 1.2.2.3 Độ trì hoãn giữa pin đến pin Một tiện ích trong việc mô tả định thời cho các linh kiện tại ngõ vào và ngõ ra cũng được cung cấp trong Verilog. Tiện ích này có thể được dùng để truy vấn lại thông tin về định thời trong mô tả tiền thiết kế ban đầu. Hơn nữa, tiện ích này cũng cho phép người viết mô hình hóa tinh chỉnh hành vi định thời của mô hình dựa trên hiện thực phần cứng. 1.2.2.4 Mô tả Bus Những tiện ích về mô hình bus và thanh ghi cũng được cung cấp bởi Verilog. Đối với nhiều cấu trúc bus khác nhau, Verilog hỗ trợ chức năng phân giải bus và wire với hệ thống logic 4 giá trị (0,1,x,z). Với sự kết hợp giữa chức năng bus logic và chức năng phân giải, nó cho phép mô hình hóa được hầu hết các loại bus. Đối với việc mô hình hóa thanh ghi, việc mô tả xung clock mức cao và những cấu trúc điều khiển định thời, có thể được sử dụng để mô tả thanh ghi với những tín hiệu xung clock và tín hiệu reset khác nhau. 1.2.2.5 Mức độ hành vi Những khối qui trình (procedural blocks) của Verilog cho phép mô tả thuật toán của những cấu trúc phần cứng. Những cấu trúc này tương tự với ngôn ngữ lập trình phần mềm nhưng có khả năng mô tả phần cứng. 1.2.2.6 Những tiện ích hệ thống Những tác vụ hệ thống trong Verilog cung cấp cho người thiết kế những công cụ trong việc tạo ra dữ liệu kiểm tra testbench, tập tin truy xuất đọc, ghi, xử lí dữ liệu, tạo dữ liệu, và mô hình hóa những phần cứng chuyên dụng. Những tiện ích hệ thống dùng cho bộ nhớ đọc và thiết bị logic lập trình được (PLA) cung cấp những phương pháp thuận tiện cho việc mô hình hóa những thiết bị này. Những tác vụ hiển thị và I/O có thể được sử dụng để kiểm soát tất cả những ngõ vào và ngõ ra dữ liệu của ứng dụng và mô phỏng. Verilog cho phép việc truy xuất đọc và ghi ngẫu nhiên đến các tập tin. 1.2.2.7 PLI Công cụ tương tác ngôn ngữ lập trình (PLI) của Verilog cung cấp một môi trường cho việc truy xuất cấu trúc dữ liệu Verilog, sử dụng một thư viện chứa các hàm của ngôn ngữ C. 1.2.3 Sơ lược về Verilog Ngôn ngữ Verilog HDL đáp ứng tất cả những yêu cầu cho việc thiết kế và tổng hợp những hệ thống số. Ngôn ngữ này hỗ trợ việc mô tả cấu trúc phân cấp của phần cứng từ mức độ hệ thống đến mức cổng hoặc đến cả mức công tắc chuyển mạch. Verilog cũng hỗ trợ mạnh tất cả các mức độ mô tả việc định thời và phát hiện lỗi. Việc định thời và đồng bộ mà được đòi [Type text] Page 22
  23. Giáo trình ngôn ngữ Verilog HDL hỏi bởi phần cứng sẽ được chú trọng một cách đặc biệt. Trong Verilog, một linh kiện phần cứng được mô tả bởi một cấu trúc ngôn ngữ gọi là module. Sự mô tả một module sẽ mô tả danh sách những ngõ vào và ngõ ra của linh kiện cũng như những thanh ghi và hệ thống bus bên trong linh kiện. Bên trong một module, những phép gán đồng thời, gọi sử dụng linh kiện và những khối qui trình có thể được dùng để mô tả một linh kiện phần cứng. Nhiều module có thể được gọi một cách phân cấp để hình thành những cấu trúc phần cứng khác nhau. Những phần tử con của việc mô tả thiết kế phân cấp có thể là những module, những linh kiện cơ bản hoặc những linh kiện do người dùng tự định nghĩa. Để mô phỏng cho thiết kế, những phần tử con trong cấu trúc phân cấp này nên được tổng hợp một cách riêng lẻ. Hiện nay có rất nhiều công cụ và môi trường dựa trên Verilog cung cấp khả năng chạy mô phỏng, kiểm tra thiết kế và tổng hợp thiết kế. Môi trường mô phỏng cung cấp những chương trình giao diện đồ họa cho bước thiết kế trước layout (front-end), những công cụ tạo dạng sóng và công cụ hiển thị. Những công cụ tổng hợp dựa trên nền tảng của Verilog và khi tổng hợp một thiết kế thì thiết bị phần cứng đích như FPGA hoặc ASIC cần phải được xác định trước. 1.3 Tổng kết Phần này đã cung cấp một cái nhìn tổng quan về những cơ chế, những công cụ và những qui trình dùng trong việc mô tả một thiết kế từ bước thiết kế đến quá trình hiện thực phần cứng. Phần này cũng nói sơ lược về thông tin kiến thức mà ta sẽ đi sâu trong các phần sau. Bên cạnh đó, nó cũng cung cấp đến người đọc lịch sử phát triển của Verilog. Cùng với việc phát triển chuẩn Verilog HDL này là sự phát triển không ngừng của các công ty nghiên cứu, xây dựng và hoàn thiện các công cụ hỗ trợ đi kèm, kết quả là tạo ra những công cụ tốt hơn và những môi trường thiết kế đồng bộ hơn. 1.4 Bài tập 1. Verilog là gì ? Tại sao ta phải sử dụng ngôn ngữ mô tả phần cứng Verilog trong thiết kế Chip? 2. Tìm hiểu môi trường thiết kế trên FPGA là QuartusII của Altera và tìm hiểu môi trường mô phỏng, môi trường tổng hợp của nó. Hãy liên tưởng, so sánh môi trường thiết kế này với môi trường mô phỏng và tổng hợp đã được trình bày trong phần này. 3. Nêu sự khác biệt giữa ngôn ngữ mô tả phần cứng nói chung (ngôn ngữ Verilog HDL nói riêng) và ngôn ngữ lập trình nói chung (ngôn ngữ C nói riêng)? 4. Tìm hiểu sự khác biệt giữa hai loại ngôn ngữ mô tả phần cứng Verilog HDL và VHDL? [Type text] Page 23
  24. Giáo trình ngôn ngữ Verilog HDL 5. Quá trình tổng hợp (synthesis) là gì? 6. Verilog HDL có thể được sử dụng để mô tả mạch tương tự (analog) trong phần cứng không ? 7. Tìm kiếm 3 công cụ mô phỏng Verilog HDL hỗ trợ miễn phí. 8. Tìm kiếm 3 tài liệu hỗ trợ việc học và nghiên cứu Verilog HDL. 9. Tìm kiếm 3 website hỗ trợ việc học và nghiên cứu Verilog HDL. 10. Tìm kiếm các công ty thiết kế chip ở Việt Nam đang sử dụng Verilog HDL trong việc thiết kế? 11. Tìm hiểu và sử dụng thành thạo hai công cụ mô phỏng QuartusII và ModelSim? [Type text] Page 24
  25. Giáo trình ngôn ngữ Verilog HDL 2 Chương 2. Qui ước về từ khóa 2.1 Khoảng trắng Khoảng trắng trong Verilog là những kí tự đặc biệt gồm có: kí tự dấu cách (Space), kí tự tab (Tab) và kí tự xuống dòng (Enter). Những kí tự này có thể được bỏ qua trừ khi nó được sử dụng để tách biệt với những kí tự đặc biệt mang ý nghĩa khác. Tuy nhiên, kí tự khoảng trắng và kí tự tab là những kí tự bình thường trong xâu và không bị bỏ qua (xem trong Mục 2.5). 2.2 Chú thích Ngôn ngữ Verilog HDL có hai cách để tạo chú thích:  Chú thích một dòng: bắt đầu bằng hai kí tự // cho đến cuối dòng.  Chú thích một khối: bắt đầu bằng hai ký tự /* và kết thúc bằng hai ký tự */. Chú thích một khối không nên quá rối rắm, không được có sự lồng nhau giữa những chú thích khối, nhưng được phép lồng chú thích 1 dòng trong chú thích khối (trong chú thích khối thì hai kí tự // không mang ý nghĩa gì đặc biệt cả). Ví dụ: x = y && y; // đây là chú thích một dòng /* đây là chú thích nhiều dòng */ /* đây là /* chú thích */ không hợp lệ */ /* đây là //chú thích hợp lệ */ 2.3 Toán tử Những toán tử như chuỗi kí tự đơn, kép hay gồm ba kí tự được dùng trong những biểu thức. Trong phần thảo luận về biểu thức (Chương 4) ta sẽ trình bày về cách sử dụng các toán tử trong biểu thức như thế nào. Những toán tử đơn thường xuất hiện bên trái của toán hạng của chúng ( i). Những toán tử kép thường xuất hiện ở giữa những toán hạng của chúng (a & b). Toán tử có điều kiện thường có hai toán tử kí tự được phân biệt bởi ba toán hạng ( (m>n) ? m : n ). 2.4 Số học Hằng số được mô tả như là hằng số nguyên hoặc hằng số thực. Ví dụ 2.1 [Type text] Page 25
  26. Giáo trình ngôn ngữ Verilog HDL 243 // số thập phân 243 9 1.4E9 // số thực 1.4x10 -5’d18 // số thập phân -18 lưu trong 5 bit 4’b1011 // số nhị phân 1011 lưu trong 4 bit 8’hEF // số thập lục phân EF lưu trong 8 bit 16’o56 // số bát phân 56 lưu trong 16 bit 4’bxxxx // số nhị phân tùy định lưu trong 4 bit 4’bzzzz // số nhị phân 4 bit có giá trị tổng trở cao 2.4.1 Hằng số nguyên Hằng số nguyên có thể được mô tả theo định dạng số thập phân, thập lục phân, bát phân và nhị phân. Có hai dạng để biểu diễn hằng số nguyên: Dạng thứ nhất là một số thập phân đơn giản, nó có thể là một chuỗi kí tự từ 0 đến 9 và có thể bắt đầu với toán tử đơn cộng ( + ) hoặc trừ (-). Ví dụ: 374 // số thập phân không dấu 374 +374 // số thập phân có dấu +374 -374 // số thập phân có dấu -374 Dạng thứ hai được mô tả dưới dạng hằng cơ số, nó gồm ba thành phần:  Thành phần đầu tiên: độ rộng hằng số, mô tả độ rộng là số bit để chứa hằng số. Nó được mô tả như là một số thập phân không dấu khác không. Ví dụ, độ rộng của hai số hexadecimal là 8 bit bởi vì mỗi một số hexadecimal cần 4 bit để chứa, thành phần này có thể có hoặc không. Ví dụ: 20‘h 473FF // số thập lục phân có độ rộng 20 bit ‘o7439 // số bát phân  Thành phần thứ hai: định dạng cơ số, bao gồm một kí tự (có thể là kí tự thường hoặc kí tự hoa) để mô tả cơ số của số đó, ta có thể thêm vào hoặc không thêm vào phía trước nó kí tự s (hoặc S) để chỉ rằng nó là một số có dấu, tiếp tục phía trước nó là một kí tự móc đơn. Những ký tự mô tả cơ số được dùng có thể là: . d, D : Hệ thập phân . h, H : Hệ lục phân . o, O : Hệ bát phân . b, B : Hệ nhị phân [Type text] Page 26
  27. Giáo trình ngôn ngữ Verilog HDL Kí tự móc đơn là bắt buộc phải có khi sử dụng ký tự mô tả cơ số, giữa kí tự ‘ và ký tự định dạng cơ số không được cách nhau bởi bất kì khoảng trắng nào. Ví dụ: 5EB // không hợp lệ (số thập lục phân đòi hỏi ‘h), đúng là 5’hEB 10o567 // không hợp lệ (thiếu dấu ’), đúng là 10’o567 8’ b 1001 // không hợp lệ (giữa ‘ và b có khoảng trắng), đúng là 4’b1001  Thành phần thứ ba, là một số không dấu, bao gồm những kí tự phù hợp với cơ số đã được mô tả trong thành phần thứ hai. Thành phần số không dấu này có thể theo sau ngay thành phần cơ số hoặc có thể theo sau thành phần cơ số bởi một khoảng trắng. Những kí tự từ a đến f của số thập lục phân có thể là kí tự thường hoặc kí tự hoa. Ví dụ 2.3 Hằng số có độ rộng bit 4’b1011 // số nhị phân 4 bit 5 ‘D 5 // số thập phân 5 bit 3’B10x // số nhị phân 3 bit với bit có trọng số thấp nhất có giá trị không xác định 12’hx // số thập lục phân 12 bit có giá trị không xác định 16’Hz // số thập lục phân 16 bit có giá trị tổng trở cao. Những số thập phân đơn giản không kèm theo độ rộng bit và định dạng cơ số được xem như là những số nguyên có dấu. Những số được mô tả bởi định dạng cơ số được xem như những số nguyên có dấu khi thành phần chỉ định s (hoặc S) được kèm thêm vào, hoặc nó sẽ được xem như những số nguyên không dấu khi chỉ có thành phần định dạng cơ số được sử dụng. Thành phần chỉ định số có dấu s (hoặc S) không ảnh hưởng đến mẫu bit được mô tả mà nó chỉ ảnh hưởng trong quá trình biên dịch. Toán tử cộng hay trừ đứng trước hằng số độ rộng là một toán tử đơn cộng (+) hay trừ (-), hai toán tử này nếu được đặt nằm giữa thành phần định dạng cơ số và số là không đúng cú pháp. Những số âm được biểu diễn dưới dạng bù hai. Ví dụ 2.4 Sử dụng dấu với hằng số 6 ‘d -7 // cú pháp không đúng -6 ‘d 7 // số bù 2 của 7, tương đương với –(6’d 7) 4 ‘shf // số có dấu (số bù 2) 4 bit ‘1111’, bằng -1, tương đương với –4’h1 -4 ‘sd15 // tương đương với –(4’sd15), hay –(-1) = 1 = 0001 8’sd? // tương đương 8’sbz Các giá trị số đặc biệt x và z: [Type text] Page 27
  28. Giáo trình ngôn ngữ Verilog HDL Một số x dùng để biểu diễn một giá trị không xác định trong những hằng số thập lục phân, hằng số bát phân và hằng số nhị phân. Một số z dùng để biểu diễn một số có giá trị tổng trở cao. Một số x có thể được thiết lập trên 4 bit để biểu diễn một số thập lục phân, trên 3 bit để biểu diễn một số bát phân, trên 1 bit để biểu diễn một số nhị phân có giá trị không xác định. Tương tự, một số z có thể được thiết lập trên 4 bit để biểu diễn một số thập lục phân, trên 3 bit để biểu diễn một số bát phân, trên 1 bit để biểu diễn một số nhị phân có giá trị tổng trở cao. Ví dụ 2.5 Tự động thêm vào bên trái reg [11:0] m, n, p, q; // m, n, p, q đều có 12 bit initial begin m = ‘h x; // tạo ra xxx n = ‘h 4x; // tạo ra 04x p = ‘h z5; // tạo ra zz5 q = ‘h 0z8; // tạo ra 0z8 end reg [15:0] e, f, g; // e, f, g đều có 16 bit e = ‘h4; // tạo ra {13{1’b0}, 3’b100} f = ‘hx // tạo ra {16{1’hx}} g = ‘hz; // tạo ra {16{1’hz}} Nếu độ rộng bit của số không dấu nhỏ hơn độ rộng được mô tả trong phần mô tả hằng số thì số không dấu sẽ được thêm vào bên trái nó là các số 0. Nếu bít ngoài cùng bên trái trong số không dấu là x hoặc z thì một x hoặc một z sẽ được dùng để thêm vào bên trái một cách tương ứng. Nếu độ rộng của số không dấu lớn hơn độ rộng được mô tả trong phần mô tả hằng số thì số không dấu sẽ bị cắt xén đi từ bên trái. Số bit dùng để tạo nên một số không có độ rộng (có thể là một số thập phân đơn giản hoặc một số không mô tả độ rộng bit) nên ít nhất là 32 bit. Những hằng số không dấu, không độ rộng mà bit có trọng số cao là không xác định (x) hoặc tổng trở cao (z) thì nó sẽ được mở rộng ra đến độ rộng của biểu thức chứa hằng số. Giá trị x và z để mô tả giá trị của một số có thể là chữ hoa hoặc chữ thường. Khi được sử dụng để mô tả một số trong Verilog, thì kí tự dấu chấm hỏi (?) có ý nghĩa thay thế cho kí tự z. Nó cũng thiết lập 4 bit lên giá trị tổng trở cao cho số thập lục phân, 3 bit cho số bát phân và 1 bit cho số nhị phân. Dấu chấm hỏi có thể được dùng để giúp việc đọc code dễ [Type text] Page 28
  29. Giáo trình ngôn ngữ Verilog HDL hiểu hơn trong trường hợp giá trị tổng trở cao là một điều kiện không quan tâm (don’t care). Ta sẽ thảo luận rõ hơn về vấn đề này khi trình bày về casez và casex. Kí tự dấu chấm hỏi cũng được dùng trong những bảng trạng thái do người dùng tự định nghĩa. Trong một hằng số thập phân, số không dấu không bao gồm những kí tự x, z hoặc ? trừ trường hợp ở đó chỉ có đúng một kí tự để chỉ ra rằng mọi bit trong hằng số thập phân là x hoăc z. Kí tự gạch dưới ( _ ) có thể dùng ở bất kì nơi đâu trong một số, ngoại trừ kí tự đầu tiên. Kí tự gạch dưới sẽ được bỏ qua. Đặc tính này có thể được dùng để tách một số quá dài để giúp việc đọc code dễ dàng hơn. Ví dụ 2.6 Sử dụng dấu gạch dưới trong mô tả số 27_195_000 16’b0011_0101_0001_1111 32 ‘h 12ab_f001 Những hằng số âm có độ rộng bit và những hằng số có dấu có độ rộng bit là những số có dấu mở rộng khi nó được gán đến một loại dữ liệu là reg bất chấp bản thân reg này có dấu hay không. Độ dài mặc định của x và z giống như độ dài mặc định của một số nguyên. 2.4.2 Hằng số thực Những số hằng số thực có thể được biểu diễn như được mô tả bởi chuẩn IEEE 754-1985, một chuẩn IEEE cho những số dấu chấm động có độ chính xác kép. Những số thực có thể được mô tả bằng một trong hai cách, một là theo dạng thập phân 6 (ví dụ, 25.13), hai là theo cách viết hàn lâm (ví dụ, 45e6, có nghĩa là 45 nhân với 10 ). Những số thực được biểu diễn với dấu chấm thập phân sẽ có ít nhất một kí số ở mỗi bên của dấu chấm thập phân. Ví dụ 2.7 2.5 1543.34592 3.2E23 or 3.2e23 5.6e-3 0.9e-0 45E13 43E-6 [Type text] Page 29
  30. Giáo trình ngôn ngữ Verilog HDL 354.156_972_e-19 (dấu gạch dưới được bỏ qua) Những dạng số sau không đúng là số thực vì chúng không có ít nhất một kí số ở mỗi bên của dấu chấm thập phân. .43 8. 7.E4 .6e-9 2.4.3 Số đảo Số thực có thể biến đổi sang số nguyên bằng cách làm tròn số thực đến số nguyên gần nhất thay vì cắt xén số bit của nó. Biến đổi không tường minh có thể thực hiện khi một số thực được gán đến một số nguyên. Những cái đuôi nên được làm tròn khác 0. Ví dụ: . Hai số thực 48.8 và 48.5 đều trở thành 49 khi được biến đổi sang số nguyên, và số 48.3 sẽ trở thành 48. . Biến đổi số thực -5.5 sang số nguyên sẽ được -6, biến đổi số 5.5 sang số nguyên sẽ được 6. 2.5 Chuỗi Một chuỗi là một dãy các kí tự được nằm trong hai dấu nháy kép(“”) và được ghi trên một dòng đơn. Những chuỗi được dùng như là những toán hạng trong biểu thức và trong những phép gán được xem như là những hằng số nguyên không dấu và được biểu diễn bởi một dãy kí tự 8 bit ASCII. Một kí tự ASCII biểu diễn bằng 8 bit. 2.5.1.1 Khai báo biến chuỗi Biến chuỗi là biến có loại dữ liệu là reg với độ rộng bằng với số kí tự trong chuỗi nhân với 8. Ví dụ 2.8 /* Để lưu trữ một chuỗi 12 kí tự “Verilog HDL!” đòi hỏi một reg có độ rộng 8*12, hoặc 96 bit */ reg [8*12:1] stringvar; initial begin stringvar = “Verilog HDL!”; end 2.5.1.2 Xử lí chuỗi Chuỗi có thể được xử lí bằng việc sử dụng các toán tử Verilog HDL. Giá trị mà được xử lí [Type text] Page 30
  31. Giáo trình ngôn ngữ Verilog HDL bởi toán tử là một dãy giá trị 8 bit ASCII. Các toán tử xử lý chuỗi được thể hiện chi tiết hơn trong phần 4.3.3. 2.5.1.3 Những kí tự đặc biệt trong chuỗi Một số kí tự chỉ được sử dụng trong chuỗi khi đứng trước nó là một kí tự mở đầu, gọi là kí tự escape “\”. Bảng bên dưới liệt kê những kí tự này và ý nghĩa của nó. Bảng 2.1 Kí tự đặc biệt trong chuỗi Chuỗi escape Kí tự tạo bởi chuỗi escape \n Kí tự xuống dòng \t Kí tự tab \\ Kí tự \ \” Kí tự “ \ddd Một kí tự được mô tả trong 1-3 kí số bát phân (0 d 7) Nếu ít hơn ba kí tự được sử dụng, kí tự theo sau không thể là một kí số bát phân. Việc thực thi có thể dẫn đến lỗi nếu kí tự được biểu diễn lớn hơn 377 2.6Định danh, từ khóa và tên hệ thống Định danh (indentifier) được dùng để gán cho một đối tượng (object) một tên duy nhất để nó có thể được gọi tới khi cần. Định danh có thể là một định danh đơn giản hoặc một định danh escaped. Một định danh đơn giản có thể là một dãy bất kì gồm các kí tự, kí số, dấu dollar ($), và kí tự gạch dưới (_). Kí tự đầu tiên của một định danh không thể là một kí số hay $; nó có thể là một kí tự chữ cái hoặc một dấu gạch dưới. Định danh sẽ là khác nhau giữa chữ thường và chữ hoa như trong ngôn ngữ lập trình C. Ví dụ 2.9 kiemtra_e net _m fault_result string_ab _wire1 n$983 Ở đây có sự giới hạn về độ dài của định danh, nhưng giới hạn này ít nhất là 1024 kí tự. Nếu một định danh vượt ra khỏi giới hạn về chiều dài đã được xác định thì lỗi có thể được thông báo ra. [Type text] Page 31
  32. Giáo trình ngôn ngữ Verilog HDL 2.6.1 Định danh với kí tự “\” Tên định danh escaped được bắt đầu với kí tự gạch chéo (\) và kết thúc bởi khoảng trắng (kí tự khoảng trắng, kí tự tab, kí tự xuống dòng). Chúng cung cấp cách thức để chèn thêm những kí tự ASCII có thể in được vào trong các kí tự có code từ 33 đến 126, hoặc giá trị thập lục phân từ 21 đến 7E). Cả hai kí tự gạch chéo (\) và kí tự khoảng trắng kết thúc đều không được xem như là thành phần của tên nhận dạng. Do đó, một định danh “\abc” sẽ được xử lí giống như định danh “abc”. Ví dụ 2.10 \net c+num \-signal \ fault-result \wirea/\wireb \{m,n} \i*(k+l) Một từ khóa trong Verilog HDL mà đứng trước nó là một kí tự escape sẽ không được biên dịch như là một từ khóa. 2.6.2 Tác vụ hệ thống và hàm hệ thống Dấu dollar ($) mở đầu một cấu trúc ngôn ngữ sẽ cho phép phát triển những tác vụ hệ thống và hàm hệ thống do người dùng định nghĩa. Những cấu trúc hệ thống không phải là ngôn ngữ thiết kế, mà nó muốn nói đến chức năng mô phỏng. Một tên theo sau dấu $ được biên dịch như là một tác vụ hệ thống hoặc hàm hệ thống. Tác vụ hệ thống/hàm hệ thống có thể được định nghĩa trong ba vi trí: Một tập hợp chuẩn những tác vụ hệ thống và hàm hệ thống.  Những tác vụ hệ thống và hàm hệ thống thêm vào được định nghĩa dùng cho PLI (Programming Language Interface).  Những tác vụ hệ thống và hàm hệ thống thêm vào được định nghĩa bởi phần mềm thực thi. Ví dụ 2.11 $time – trả về thời gian chạy mô phỏng hiện tại $display – tương tự như hàm printf trong C $stop – ngừng chạy mô phỏng $finish – hoàn thành chạy mô phỏng [Type text] Page 32
  33. Giáo trình ngôn ngữ Verilog HDL $monitor – giám sát chạy mô phỏng 2.7 Bài tập 1. Nêu tác dụng và sự khác biệt giữa hai hàm hệ thống $monitor và $display khi sử dụng hai hàm hệ thống này trong quá trình mô phỏng? 2. Làm sao có thể đọc và ghi một file dữ liệu trong mô tả phần cứng Verilog HDL (giả sử file chứa nội dung bộ nhớ khởi tạo)? 3. Hãy tìm thêm 10 tác vụ hệ thống và nêu ý nghĩa của chúng? [Type text] Page 33
  34. Giáo trình ngôn ngữ Verilog HDL 3 Chương 3. Loại dữ liệu trong Verilog 3.1 Khái quát Verilog chỉ hỗ trợ những loại dữ liệu đã được định nghĩa trước. Những loại dữ liệu này bao gồm dữ liệu bit, mảng bit, vùng nhớ, số nguyên, số thực, sự kiện, và độ mạnh của dữ liệu. Những loại này định nghĩa trong phần lớn mô tả của Verilog. Verilog chủ yếu xử lí trên bit và byte khi mô tả mạch điện tử. Loại số thực thì hữu dụng trong việc mô tả độ trì hoãn và định thời, nó cũng rất hữu dụng trong việc mô hình hóa ở mức cao như là phân tích xác suất kết nối mạch trong hệ thống và những giải thuật xử lí tín hiệu số. Loại dữ liệu phần cứng bao gồm net và reg. Thông thường những loại này có thể được xem như là dây kết nối và thanh ghi. Dữ liệu net có thể được khai báo chi tiết hơn để tạo ra những loại dữ liệu khác như tri-stated hay non-tri-stated và phụ thuộc vào các xử lí nhiều kết nối sẽ tạo ra những phép and, or hoặc dùng giá trị trước đó. Phần tiếp theo sẽ trình bày chi tiết về những vấn đề này. 3.2 Những hệ thống giá trị Mỗi loại dữ liệu có những mục đích cụ thể của nó trong việc mô tả. Những hệ thống giá trị định nghĩa những loại giá trị khác nhau đã được định nghĩa trong ngôn ngữ và bao gồm cả những thao tác giúp hỗ trợ những hệ thống giá trị này. Chúng cũng có những định nghĩa hằng số tương ứng. Trong Verilog có nhiều giá trị khác nhau như:  bits and integers(32 bits), time (64 bits): bit-vectors và integers có thể phối hợp một cách tự do. Integers được định nghĩa có 32 bit. Giá trị time có 64 bit. Thực sự bit có hai loại sau: 4 giá trị trạng thái (0,1,x,z); được biết như là giá trị logic. 128 loại trạng thái: gồm 4 trạng thái và 64 độ mạnh (8 cho độ mạnh ‘0’ và 8 cho độ mạnh ‘1’) .  Loại floating point (số thực)  Chuỗi kí tự  Giá trị độ trì hoãn – Những giá trị này có thể là single, double, triplet hay n-tuple để chỉ độ trì hoãn cạnh lên, cạnh xuống hoặc sự chuyển đổi khác của tín hiệu.  Giá trị chuyển trạng thái - (01) – chuyển trạng thái từ 0 sang 1. Giá trị này có thể có trong những linh kiện cơ bản do người dùng định nghĩa hoặc trong những khối mô tả (specify blocks) [Type text] Page 70
  35. Giáo trình ngôn ngữ Verilog HDL  Những giá trị có điều kiện/Boole – true/false hoặc 0/1  units (chỉ dùng cho timescale) – femtoseconds (fs) đến seconds (s) 3.3 Khai báo loại dữ liệu 3.3.1 Giới thiệu Những loại dữ liệu khác nhau trong Verilog được khai báo bằng phát biểu khai báo dữ liệu. Những phát biểu này xuất hiện trong những định nghĩa module trước khi sử dụng và một số trong chúng có thể được khai báo bên trong những khối tuẩn tự được đặt tên. Thêm vào đó, những loại giá trị có thể phân biệt với những loại của dữ liệu khác, những đặc tính phần cứng của wires so với registers cũng được phân biệt như là những khai báo net so với khai báo reg trong Verilog. Từ driving nghĩa là điều khiển được dùng trong những mô tả phần cứng để mô tả cách thức một giá trị được gán đến một phần tử. Nets và regs là hai phần tử dữ liệu chính trong Verilog. Nets được điều khiển một cách nối tiếp từ những phép gán nối tiếp (continuous assignments) hoặc từ những phần tử cấu trúc như module ports, gates, transistors hoặc những phần tử cơ bản do người dùng tự định nghĩa. Regs được điều khiển một cách chặt chẽ từ những khối hành vi (behavioural blocks). Nets thông thường được thực thi như là wires trong phần cứng và regs thì có thể là wires hoặc phần tử tạm hoặc flip-flops (registers). Những loại dữ liệu khác nhau trong Verilog được khai báo gồm những loại sau:  parameter: Loại này là những biểu thức giá trị hằng số được phân tích sau quá trình biên dịch và cho phép modules được gán tham số.  input, output, inout: Những loại dữ liệu này định nghĩa chiều và độ rộng của một port.  net : Đây là loại dữ liệu dùng cho việc kết nối hoặc wire (dây nối) trong phần cứng với sự phân tích khác nhau.  reg: Đây là loại dự liệu trừu tượng giống như là một thanh ghi (register) và được điều khiển theo hành vi.  time: Đây là loại dữ liệu lưu trữ khoảng thời gian như độ trì hoãn và thời gian mô phỏng.  integer: Đây là loại dữ liệu số nguyên.  real: Đây là loại dữ liệu floating point hay số thực  event: Đây là dữ liệu để chỉ ra rằng một cờ hiệu được bật tích cực. Tất cả hững loại dữ liệu này có thể được khai báo ở mức độ module. Những mô tả khác trong Verilog với những khả năng tạo lập mục đích bao gồm những tác vụ, những hàm và những khối begin-end được đặt tên. Nets được điều khiển không theo hành vi (non-behaviorally) nên do đó [Type text] Page 71
  36. Giáo trình ngôn ngữ Verilog HDL nó không thể được khai báo cho những mục đích khác, tất cả những loại dữ liệu khác có thể được thể hiện trong những tác vụ và trong những khối begin- end. Ví dụ 3.1 input a, b; reg [15:0] c; time tg; Dòng đầu tiên trong ví dụ trên là một dòng khai báo input, dòng thứ hai là một khai báo dữ liệu reg 16 bit. Dòng cuối cùng là khai báo cho một biến được đặt tên là tg. 3.4 Khai báo loại dữ liệu net 3.4.1 Giới thiệu Net là một trong nhiều loại dữ liệu trong ngôn ngữ mô tả Verilog dùng để mô tả dây kết nối vật lí trong mạch điện. Net sẽ kết nối những linh kiện ở mức cổng được gọi ra, những module được gọi ra và những phép gán nối tiếp. Ngôn ngữ Verilog cho phép đọc giá trị từ một net từ bên trong những mô tả hành vi, nhưng ta không thể gán một giá trị cho một net bên trong những mô tả hành vi. Một net sẽ không lưu giữ giá trị của nó. Nó phải được điều khiển bởi một trong hai cách sau: . Bằng việc kết nối net đến ngõ ra của một cổng hay một module. . Bằng việc gán một giá trị đến net trong một phép gán nối tiếp. Những loại net khác nhau được định nghĩa trong Verilog được mô tả bên dưới và trong Bảng 3.1 sẽ tóm tắt sự phân giải logic của chúng. Sự phân giải logic là một qui định để giải quyết xung đột xảy ra khi có nhiều mức logic điều khiển một net.  wire: một net với giá trị 0, 1, x và sự phân giải logic được dựa trên sự tương đương.  wand: một net với giá trị 0, 1, x và sự phân giải logic được dựa trên nguyên tắc của phép wired and.  wor: một net với giá trị 0, 1, x và sự phân giải logic được dựa trên wired or.  tri: một net với giá trị 0, 1, x, z và sự phân giải logic được dựa trên nguyên tắc của bus tri-state.  tri0: một net với giá trị 0, 1, x, z và sự phân giải logic được dựa trên nguyên tắc của bus tri-state và một giá trị mặc định là 0 khi không được điều khiển.  tri1: một net với giá trị 0, 1, x, z và sự phân giải logic được dựa trên nguyên tắc của bus tri-state và một giá trị mặc định là 1 khi không được điều khiển. [Type text] Page 72
  37. Giáo trình ngôn ngữ Verilog HDL  trior: một net với giá trị 0, 1, x, z và sự phân giải logic được dựa trên nguyên tắc của tri-state cho giá trị z-non-z sử dụng hàm or của giá trị non-z.  triand: một net với giá trị 0, 1, x, z và sự phân giải logic được dựa trên nguyên tắc của tri-state cho giá trị z-non-z sử dụng hàm and của giá trị non-z.  trireg: một net với giá trị 0, 1, x, z và sự phân giải logic được dựa trên nguyên tắc của tri-state cùng với giá trị lưu trữ điện tích (giá trị trước được dùng để phân giải giá trị mới).  supply0, supply1: tương ứng là gnd và vdd. Bảng 3.1 Sự phân giải của các loại net tri/wire 0 1 X Z triand/wand 0 1 X Z 0 0 X X 0 0 0 0 0 0 1 X 1 X 1 1 0 1 X 1 X X X X X X 0 X X X Z 0 1 X X Z 0 1 X Z trior/wor 0 1 X Z tri0 0 1 X Z 0 0 1 X 0 0 0 0 0 0 1 1 1 1 1 1 X 1 X 1 X X 1 X X X X X X X Z 0 1 X Z Z 0 1 X 0 trireg 0 1 X Z tri1 0 1 X Z 0 0 1 X 0 0 0 X X 0 1 1 1 1 1 1 X 1 X 1 X X 1 X X X X X X X Z 0 1 X P Z 0 1 X 1 3.4.2 Wire và Tri Loại dữ liệu wire là một loại đơn giản để kết nối giữa hai linh kiện. Dữ liệu wire dùng cho những net được điều khiển bởi một cổng linh kiện đơn hay trong phép gán nối tiếp (continuous assignments). Trong Ví dụ 3.2 những khai báo 2-wire được tạo ra. Khai báo đầu tiên mô tả wire đơn (scalar wire) a1. Khai báo thứ hai mô tả một mảng (vector) b2 với 3 bits. Bit trọng số [Type text] Page 73
  38. Giáo trình ngôn ngữ Verilog HDL cao nhất (MSB) của nó có trọng số là 2 và bit trọng số thấp nhất (ISB) có trọng số là 0. Ví dụ 3.2 wire a1; wire [2:0] b2; tri abc Dữ liệu tri thì hoàn toàn giống với dữ liệu wire về cú pháp sử dụng và chức năng tuy nhiên nó khác với dữ liệu wire ở chỗ, dữ liệu tri được dùng cho những net được điều khiển bởi nhiều cổng linh kiện ngõ ra. Loại dữ liệu tri (tri-state) là loại dữ liệu đặc biệt của wire, trong đó, sự phân giải giá trị của net được điều khiển bởi nhiều linh kiện điều khiển, được thực hiện bằng việc sử dụng những qui luật của bus tri-state. Tất cả các biến mà điều khiển net tri phải có giá trị Z (tổng trở cao), ngoại trừ một biến làn biến đơn xác định giá trị của net tri. Trong Ví dụ 3.3, ba biến điều khiển biến out. Chúng được thiết lập trong module khác để chỉ một linh kiện điều khiển tích cực trong một thời điểm. Ví dụ 3.3 module tri_kiemtra (out, m, n,p); input [1:0] select ,m ,n, p; output out; tri out; assign out = m; // tạo kết nối cho net tri assign out = n; assign out = p; endmodule module mnp (m, n, p, select) output m, n, p; input [1:0] select; always @(select) begin m = 1’bz; // thiết lập tất cả các biến có giá trị Z n = 1’bz; p = 1’bz; case (select) // chỉ thiết lập một biến non-Z 2’b00: m = 1’b1; 2’b01: n = 1’b0; 2’b10: p = 1’b1; [Type text] Page 74
  39. Giáo trình ngôn ngữ Verilog HDL endcase end endmodule module top_tri_test ( out, m, n, p, select); input [1:0] select; input m, n, p; output out; tri out; mnp (m, n, p, select); tri_test (out, m, n, p); endmodule 3.4.3 Wired net Wired Nets bao gồm những loại dữ liệu wor, wand, trior và triand. Chúng được dủng để mô hình giá trị logic của net. Những wired net trên có bảng sự thật khác nhau để phân giải những xung đột nếu xảy ra khi có nhiều cổng linh kiện cùng điều khiển một net. 3.4.3.1 Wand và triand Nets Wand và triand là loại dữ liệu đặc biệt của wire dùng hàm and để tìm giá trị kết quả khi nhiều linh kiện điều khiển một net, hay nói cách khác nếu có bất kì ngõ ra linh kiện điều khiển nào có giá trị 0 thì giá trị của net được điều khiển sẽ là 0. Trong Ví dụ 3.4, hai biến điều khiển biến out. Giá trị của out được xác định bằng hàm logic and giữa b1 và b2. Ví dụ 3.4 module wand_test (out, b1,b2); input b1, b2; output out; wand out; //out = b1 and b2 assign out = b1; //b1 điều khiển out assign out = b2; //b2 điều khiển out endmodule Ta có thể gán một giá trị trì hoãn trong khai báo wand, và ta có thể sử dụng những từ khóa đơn (scalar) và mảng (vector) cho việc mô phỏng. [Type text] Page 75
  40. Giáo trình ngôn ngữ Verilog HDL 3.4.3.2 Wor và Tri or Loại dữ liệu wor và trior là loại dữ liệu đặc biệt của wire dùng hàm or để tìm giá trị kết quả khi nhiều linh kiện điều khiển một net, hay nói cách khác nếu có bất kì ngõ ra linh kiện điều khiển nào có giá trị 1 thì giá trị của net được điều khiển sẽ là 1. Trong Ví dụ 3.5, hai biến điều khiển biến out. Giá trị của out được xác định bằng hàm logic OR giữa a1 và a2. Ví dụ 3.5 module wor_test(a1,a2); input a1, a2; ouput out; wor out; // out = a1 or a2 assign out = a1; // a1 điều khiển out assign out = a2; // a2 điều khiển out endmodule 3.4.4 Tri reg net Net trireg được dùng để mô hình giá trị điện dung lưu giữ trên net của mạch điện, nó có khả năng lưu giữ giá trị điện tích. Một trireg có thể là một trong hai trạng thái sau: Trạng thái được điều khiển (driven state): Khi có ít nhất một ngõ ra của linh kiện điều khiển net trireg có giá trị 1, 0 hoặc x thì giá trị này sẽ được truyền đến net trireg, và giá trị này điều khiển giá trị của net trireg. Trạng thái lưu giữ điện dung: Khi tất cả các ngõ ra của linh kiện điều khiển net trireg đều có giá trị tổng trở cao (z), thì net trireg sẽ lưu giữ giá trị cuối cùng mà nó ở trạng thái được điều khiển. Giá trị tổng trở cao z của các ngõ ra linh kiện điều khiển sẽ không được truyền đến net trireg. Do đó, net trireg sẽ luôn có giá trị 0 hay 1 hoặc x và không có giá trị z. Độ mạnh giá trị trên net trireg trong trạng thái lưu giữ điện dung được mô tả bởi độ rộng, đó có thể là lớn (large), vừa (medium) hay nhỏ (small) với giá trị mặc định là medium nếu nó không được mô tả. Trong trạng thái được điều khiển, độ mạnh của net trireg sẽ phụ thuộc vào độ mạnh của linh kiện điều khiển như supply, strong, pull, weak mà ta sẽ thảo luận sau. Như một mô hình Verilog như phía dưới, ta sẽ lấy được giá trị kết quả của wire trireg khi transistor điều khiển nó bị tắt. Ví dụ 3.6 module kiemtra; reg c0, c1, i1, i2; tri d0, d1, d2; trireg d; [Type text] Page 76
  41. Giáo trình ngôn ngữ Verilog HDL and(d0, il, i2); nmos nl (d1, d0, c0); nmos n2(d, d1, c1); initial begin $monitor(“time = %d d =%d c =%d c1=%d d0=%d d1=%d i1=%d i2=%d”, $time, d, c0, c1, d0, d1, i1, i2); #1 i1 = 1; i2 = l; c0 = l; c1 = 1; #5 c0 = 0; end endmodule Simulation result: time = 0 d= x c0=x c1=x d0=x d1=x i1=x i2=x time = 1 d= 1 c1=1 c1=1 d0=1 d1=1 i1=1 i2=1 time = 6 d= 1 c0=0 c1=1 d0=1 d1=0 i1=1 i2=1 3.4.5 Tri 0 và Tri 1 Nets Net tri0 và tri1 dùng để mô hình những net với linh kiện điện trở kéo lên hoặc kéo xuống. Một net tri0 sẽ tương đương với một net được điều khiển liên tục bởi giá trị 0 với độ mạnh pull. Một net tri1 sẽ tương đương với một net được điều khiển liên tục bởi giá trị 1 với độ mạnh pull. Khi không có linh kiện điều khiển net tri0, giá trị của nó vẫn là 0 với độ mạnh pull. Khi không có linh kiện điều khiển net tri1, giá trị của nó vẫn là 1 với độ mạnh pull. Khi có nhiều linh kiện điều khiển net tri0 hoặc tri1, thì sự phân giải độ mạnh của các linh kiện điều khiển với độ mạnh pull của net tri0 hoặc tri1, sẽ xác định giá trị của net. 3.4.6 Supply0 và Supply1 Nets Loại dữ liệu supply0 và supply1 định nghĩa những net wire được mắc cố định đến mức logic 0 (nối đất, vss) và logic 1 (nguồn cung cấp, vdd). Việc sử dụng supply0 và supply1 tương tự như khai báo một wire và sau đó gán giá trị 0 hoặc 1 lên nó. Trong Ví dụ 3.7, power được nối lên nguồn cung cấp (luôn là logic 1 – có độ mạnh lớn nhất) và gnd được nối đến đất (ground) (uôn là logic 0 – có độ mạnh nhất). Ví dụ 3.7 [Type text] Page 77
  42. Giáo trình ngôn ngữ Verilog HDL supply0 gnd; supply1 power; 3.4.7 Thời gian trì hoãn trên net Trong thực tế bất kì net nào trong mạch điện tử cũng tạo ra độ trì hoãn trên net. Trong Verilog, độ trì hoãn có thể được khai báo kết hợp trong phát biểu khai báo net. Những giá trị độ trì hoãn này là thời gian trì hoãn, được tính từ khi tín hiệu tại ngõ ra của linh kiện điều khiển thay đổi, cho đến khi tín hiệu trên net thực sự thay đổi. Độ trì hoãn được mô tả bởi số hoặc biểu thức theo sau biểu tượng ‘#’. Những giá trị này là hằng số, tham số, biểu thức của chúng hay có thể là những biểu thức động dùng những biến số khác. Độ trì hoãn có thể là rise, fall, hay hold, mỗi loại trì hoãn này có thể có ba giá trị - minimum, typical và maximum. Sự mô tả độ trì hoãn rise, fall, hold được phân biệt bởi dấu phẩy (,) và sự mô tả min:typ:max được phân biệt bởi dấu hai chấm (:):  Độ trì hoãn rise (cao lên) bao gồm thời gian trì hoãn khi giá trị tín hiệu thay đổi từ 0 lên 1, 0 đến x và từ x đến 1.  Độ trì hoãn fall (thấp xuống) bao gồm thời gian trì hoãn khi giá trị tín hiệu thay đổi từ 1 xuống 0, 1 đến x và từ x đến 0.  Độ trì hoãn hold (thời gian thay đổi đến z) bao gồm thời gian trì hoãn khi giá trị tín hiệu thay đổi từ 0 lên z, 1 đến z và từ x đến z. Khái niệm độ trì hoãn này cũng được dùng cho việc định nghĩa độ trì hoãn của cổng, transistor, linh kiện cơ bản do người dùng tự định nghĩa và những mô tả hành vi. Ví dụ 3.8: tri #9 t1, t2; wire #(10,9,8) a1, a2; wand #(10:8:6, 9:8:6) a3; Trong Ví dụ 3.8, dòng đầu tiên mô tả t1, t2 có thời gian trì hoãn rise, fall, hold đều là 9 đơn vị thời gian. Dòng thứ hai, wire a1 và a2 định nghĩa ba giá trị khác nhau cho ba sự thay đổi – 10 cho rise, 9 cho fall và 8 cho hold. Dòng cuối cùng, wand a3 định nghĩa giá trị min, type cho cả ba sự thay đổi rise, fall, hold. Ví dụ 3.9: wire a1, a2; tri[7:0] t1, t2; trireg large trg1, trg2; [Type text] Page 78
  43. Giáo trình ngôn ngữ Verilog HDL triand [31:0] #(10:5) gate1; Trong ví dụ trên, dòng đầu tiên với từ khóa wire khai báo a1 và a2 là wire đơn (scalar wire hay single bit). Dòng thứ hai khai báo hai vector wire 8 bit t1 và t2 có loại dữ liệu là tri. Dòng kế tiếp khai báo net có khả năng lưu giữ điện dung trg1 và trg2 với độ lớn điện dung là large. Dòng cuối cùng khai báo một net có độ rộng 32 bit có loại dữ liệu là triand với độ trì hoãn là tối thiểu (minimum) và trung bình (typical). 3.5 Khai báo loại dữ liệu biến - reg Khai báo reg được thực hiện cho tất cả những tín hiệu mà được điều khiển từ những mô tả hành vi. Loại dữ liệu reg lưu giữ một giá trị được cho đến khi nó được gán một giá trị mới trong một mô tả tuần tự (khối initial hoặc always). Loại dữ liệu reg thì có mức độ trừu tượng hơn so với loại dữ liệu net nhưng nó có quan hệ mật thiết với khái niệm thanh ghi (register), với khả năng lưu giữ giá trị và có thể được xem như là một register trong phần cứng. Tuy nhiên, chúng cũng có thể được xem như là wire hoặc phần tử nhớ tạm thời mà không phải là phần tử thực trong phần cứng, điều này phụ thuộc vào việc sử dụng chúng bên trong khối mô tả hành vi. Ví dụ 3.10 reg reg1, reg2; reg [63:0] data1, data2, data3; 3.6 Khai báo port 3.6.1 Giới thiệu Ta phải khai báo thật tường minh về chiều (input, output hay bidirectional) của mỗi port xuất hiện trong danh sách khai báo port. Trong Verilog định nghĩa ba loại port khác nhau, đó là input, output và inout. Loại dữ liệu của port có thể là net hoặc reg. Loai dữ liệu reg chỉ có thể xuất hiện ở port output. Hằng số và biểu thức luôn nằm phía dưới khai báo port. 3.6.2 input Tất cả port input của một module được khai báo với một phát biểu input. Loại dữ liệu mặc định của input port là wire và được điều khiển bởi cú pháp của wire. Ta có thể khai báo độ rộng của một input như một mảng (vector) của những tín hiệu. Những phát biểu input có thể xuất hiện ở bất cứ vị trí nào trong mô tả thiết kế nhưng chúng phải được khai báo trước khi chúng được sử dụng. Ví dụ 3.11 [Type text] Page 79
  44. Giáo trình ngôn ngữ Verilog HDL input m; input [2:0] n; 3.6.3 output Tất cả port output của một module được khai báo với một phát biểu output. Nếu không có một loại dữ liệu khác như là reg, wand, wor, hoặc tri được khai báo, thì output port sẽ có loại dữ liệu mặc định là wire và nó cũng được điều khiển bởi cú pháp của wire. Một phát biểu output có thể xuất hiện ở bất cứ vị trí nào trong mô tả thiết kế, nhưng nó phải được khai báo trước khi được sử dụng. Ta có thể khai báo độ rộng của một output như một mảng (vector) của những tín hiệu. Nếu ta sử dụng loại dữ liệu reg để khai báo cho output thì reg phải có cùng độ rộng với độ rộng của mảng (vector) của tín hiệu. Ví dụ 3.12 output abc; // khai báo output abc kiểu wire output [2:0] bcd; reg [2:0] bcd; //reg bcd phải có cùng kích thước trên khai báo output 3.6.4 inout Ta có thể khai báo port hai chiều (bidirectional) với phát biểu inout. Một port inout có loại dữ liệu là wire và được điều khiển bởi cú pháp của wire. Ta phải khai báo port inout trước khi nó được sử dụng. Ví dụ 3.13 inout a: inout [2:0] b; Ví dụ 3.14 module fulladder(cout, sum, in1, in2, in3); input in1, in2, in3; // khai báo 3 ngõ vào output cout, sum; //khai báo 2 ngõ ra wire in1, in2, in3; //khai báo kiểu dữ liệu reg cout, sum; //khai báo kiểu dữ liệu endmodule 3.7 Khai báo mảng và phần tử nhớ một và hai chiều. 3.7.1 Giới thiệu Verilog chỉ hỗ trợ khai báo mảng một và hai chiều. Những mảng một chiều được gọi là [Type text] Page 80
  45. Giáo trình ngôn ngữ Verilog HDL bit-vectors và nó có thể là loại dữ liệu net hoặc reg. Những mảng hai chiều được gọi là những phần tử nhớ và là loại dữ liệu reg. Ta có thể định nghĩa độ rộng cho tất cả các loại dữ liệu được trình bày trong chương này. Việc định nghĩa độ rộng cung cấp một cách để tạo ra một bit-vector. Cú pháp của một mô tả độ rộng là [msb:lsb]. Những biểu thức của msb (bit có trọng số lớn nhất) và lsb (bit có trọng số nhỏ nhất) phải là những biểu thức có giá trị hằng khác 0. Những biểu thức có giá trị hằng chỉ có thể tạo nên bởi những hằng số, những tham số của Verilog và các toán tử. Không có giới hạn trong việc định nghĩa độ rộng tối đa của một bit- vector trong Verilog, tuy nhiên việc giới hạn này có thể sẽ phụ thuộc vào công cụ mô phỏng, tổng hợp, hoặc những công cụ khác. 3.7.2 Mảng net Ví dụ 3.15 wire [63:0] bus; Ở Ví dụ 3.15 mô tả việc khai báo một mảng wire có độ rộng 64 bits. Ví dụ 3.16 wire vectored [31:0] bus1; wire scalared [31:0] bus2; Ở Ví dụ 3.16, ta sử dụng hai từ khóa chỉ dẫn vectored và scalared, chúng đều được dùng để khai báo multi-bit Nets, tuy nhiên chúng khác nhau ở chỗ có cho phép mô tả từng bit hay từng phần của net hay không, với vectored net, việc chọn từng bit là không được phép, còn với scalared net thì được phép: assign bus1 [1] = 1’b1; // sai cú pháp vì sử dụng việc chọn bit của một vectored net. assign bus2 [1] = 1’b1; // đúng vì việc chọn bit của một scalared net là được phép. Trình biên dịch chấp nhận cú pháp của những cấu trúc mô tả Verilog này, tuy nhiên chúng sẽ bị bỏ qua khi mạch được tổng hợp ra phần cứng. 3.7.3 Mảng thanh ghi Ví dụ 3.17: Khai báo mảng thanh ghi reg [7:0] Areg // thanh ghi 8 bit [Type text] Page 81
  46. Giáo trình ngôn ngữ Verilog HDL 3.7.4 Mảng phần tử nhớ Ví dụ 3.18 : Khai báo mảng phần tử nhớ reg Amem [7:0]; // mảng 8 thanh ghi, mỗi thanh ghi có độ rộng mặc định reg Bmem [7:0][0:3]; // reg [7:0] Cmem [0:3]; // mảng 4 thanh ghi, mỗi thanh ghi 8 bit reg[2:0] Dmem [0:3][0:4]; [Type text] Page 82
  47. Giáo trình ngôn ngữ Verilog HDL 3.8 Khai báo loại dữ liệu biến (số nguyên, thời gian, số thực, và thời gian thực) 3.8.1 Giới thiệu Thêm vào khả năng mô hình hóa cho phần cứng trong Verilog, ta có thể sử dụng thêm một số loại dữ liệu biến khác ngoài dữ liệu biến reg. Mặc dù biến dữ liệu reg có thể được dùng cho những chức năng tổng quát như đếm thời gian, lưu giữ sự thay đổi giá trị của net, biến dữ liệu integer và time thì cung cấp sự thuận lợi và dễ đọc hiểu hơn trong việc mô tả thiết kế. 3.8.2 Integer Loại dữ liệu integer là biến có chức năng tổng quát được dùng để tính toán số lượng. Nó không được xem như là thanh ghi trong phần cứng thiết kế. Loại dữ liệu integer có độ rộng 32 bit, nó có thể được gán và sử dụng hoàn toàn giống như loại biến dữ liệu reg. Phép gán qui trình (procedural assignment) được dùng để kích sự thay đổi giá trị của loại dữ liệu integer. Những phép tính trên biến dữ liệu integer sẽ tạo ra những kết quả ở dưới dạng bù 2. Ví dụ 3.19: Khai báo biến integer integer i1, i2; 3.8.3 Time Biến dữ liệu time có độ rộng 64 bit, biến này thường được dùng để lưu giữ giá trị output của hàm hệ thống $time, hoặc để tính toán thời gian chạy mô phỏng trong những trường hợp mà ở đó việc kiểm tra định thời là bắt buộc, hoặc cho những mục đích dò tìm và phát hiện lỗi của thiết kế trong quá trình mô phỏng. Loại dữ liệu time có thể được gán và sử dụng hoàn toàn giống như loại biến dữ liệu reg. [Type text] Page 83
  48. Giáo trình ngôn ngữ Verilog HDL Phép gán qui trình (procedural assignment) được dùng để kích sự thay đổi giá trị của loại dữ liệu time. Ví dụ 3.20: Khai báo kiểu dữ liệu time time t1, t2; 3.8.4 Số thực (real) và thời gian thực (realtime) Bên cạnh biến dữ liệu integer và time, Verilog còn có hỗ trợ việc sử dụng hằng số thực và biến dữ liệu thực (real). Ngoại trừ 3 ngoại lệ như trình bày phía dưới đây thì biến dữ liệu real có thể được sử dụng tương tự như integer và time: 1. Không phải tất cả các phép toán trong Verilog có thể được sử dụng với những số thực. Các bảng 3.2 và 3.3 cho biết các toán tử và phép toán không được phép dùng với số thực và toán tử số thực (xem thêm Mục 4.2.1). Bảng 3.2 Danh sách các toán tử không được phép sử dụng đối với số thực unary + unary - Toán tử một ngôi (Unary operation) + - * / Toán tử số học (Arithmetic) >, >=, > >> Toán tử dịch (shift) 2. Biến dữ liệu không có khai báo độ rộng của biến, việc tính toán được thực hiện dùng chuẩn định dạng IEEE floating point. 3. Biến dữ liệu có giá trị mặc định là 0. Thời gian thực (realtime) được khai báo và sử dụng tương tự như số thực (real), chúng có [Type text] Page 84
  49. Giáo trình ngôn ngữ Verilog HDL thể hoán đổi cho nhau. Ví dụ 3.21 real float; realtime rtime; 3.9 Khai báo tham số 3.9.1 Giới thiệu Trong Verilog HDL, loại dữ liệu tham số (parameter) không thuộc loại dữ liệu biến (reg, integer, time, real, realtime) cũng như loại dữ liệu net (wire, tri, wand, wor, ). Dữ liệu tham số không phải là biến mà chúng là hằng số. Có hai loại tham số trong Verilog đó là:  Tham số module (module parameter): parameter và localparam.  Tham số đặc tả (specify parameter): specparam. Cả hai loại tham số trên đều được phép khai báo độ rộng. Mặc định, parameter và specparam sẽ có độ rộng đủ để chứa giá trị của hằng số, ngoại trừ khi tham số đó có khai báo độ rộng. Việc khai báo trùng tên giữa net, biến hay tham số là không được phép. 3.9.2 Tham số module (module parameter) Tham số module có hai loại khai báo: parameter và localparam (local parameter). 3.9.2.1 Parameter 3.9.2.1.1 Giới thiệu Giá trị của khai báo parameter trong một module có thể được thay đổi từ bên ngoài module đó bằng phát biểu defparam hoặc phát biểu gọi thể hiện (instance) của module đó. Thông thường khai báo parameter được dùng để mô tả định thời hoặc độ rộng của biến. Ví dụ 3.22 parameter msb = 1; // định nghĩa tham số msb có giá trị hằng số là 1 parameter e = 43, f =789; // định nghĩa hai hằng số parameter r = 46.7; // khai báo r là một hằng số thực parameter byte_size = 9, byte_mask = byte_size - 6; parameter average_delay = (r + f) / 2; parameter signed [3:0] mux_selector = 0; parameter real r1 = 3.6e19; parameter p1 = 13'h7e; parameter [31:0] dec_const = 1'b1; // giá trị được đổi sang 32 bit [Type text] Page 85
  50. Giáo trình ngôn ngữ Verilog HDL parameter newconst = 3'h4; // ngụ ý là tham số này có độ rộng [2:0] parameter newconst = 4; // ngụ ý là tham số này có độ rộng tối thiểu là 32 bit. 3.9.2.1.2 Thay đổi giá trị của tham số khai báo parameter Một tham số module có thể có mô tả loại dữ liệu và mô tả độ rộng. Sự tác động của giá trị tham số mới khi nó đè lên giá trị của tham số đã được khai báo ban đầu trong module, với mô tả loại dữ liệu và mô tả độ rộng sẽ tuân theo những qui luật sau:  Một khai báo tham số mà không mô tả loại dữ liệu và độ rộng, sẽ có loại dữ liệu và độ rộng mặc định của giá trị cuối cùng được gán vào tham số đó. Một khai báo tham số mà không mô tả loại dữ liệu mà chỉ mô tả độ rộng, thì độ rộng của tham số sẽ không đổi, còn loại dữ liệu sẽ là unsigned khi giá trị mới được đè lên. Một khai báo tham số mà chỉ mô tả loại dữ liệu mà không mô tả độ rộng, thì loại dữ liệu của tham số sẽ không đổi, còn độ rộng sẽ có giá trị đủ để chừa giá trị mới được đè lên.  Một khai báo tham số vừa mô tả loại dữ liệu là có dấu, vừa mô tả cả độ rộng, thì loại dữ liệu và độ rộng của tham số cũng sẽ không đổi khi giá trị mới được đè lên. Trong Verilog có hai cách để thay đổi giá trị của tham số được khai báo bởi parameter: Một là phát biểu defparam, với phát biểu này nó sẽ cho phép gán giá trị mới vào tham số trong module bằng cách dùng tên gọi một cách phân cấp.  Hai là phép gán giá trị tham số khi gọi instance của module đó, bằng cách này sẽ cho phép thay đổi giá trị tham số trong cùng một dòng với việc gọi instance của module đó. 3.9.2.1.2.1 Phát biểu defparam Sử dụng phát biểu defparam, giá trị tham số có thể được thay đổi bên trong instance của module thông qua việc sử dụng tên phân cấp của tham số. Tuy nhiên, phát biểu defparam được mô tả trong một instance hoặc một dãy các instance thì sẽ không làm thay đổi giá trị tham số trong những instance khác của cùng một module. Biểu thức bên phải của phép gán defparam là biểu thức hằng số chỉ bao gồm số và những tham số tham chiếu đã được khai báo trước đó trong cùng module với phát biểu defparam. Phát biểu defparam đặc biệt hữu dụng vì ta có thể nhóm tất cả các phép gán thay đổi giá trị các tham số của các module khác nhau chỉ trong một module. Trong trường hợp có nhiều phát biểu defparam cho một tham số duy nhất thì giá trị tham số đó sẽ lấy giá trị của phát biểu defparam sau cùng. Nếu phát biểu defparam của một tham số được khai báo trong nhiều file khác nhau thì giá trị của tham số đó sẽ không được xác định. Ví dụ 3.23 [Type text] Page 86
  51. Giáo trình ngôn ngữ Verilog HDL module top; reg clk; reg [0:4] in1; reg [0:9] in2; wire [0:4] o1; wire [0:9] o2; vdff m1 (o1, in1, clk); vdff m2 (o2, in2, clk); endmodule module vdff (out, in, clk); parameter size = 1, delay = 1; // hai tham số theo thứ tự input [0:size-1] in; input clk; output [0:size-1] out; reg [0:size-1] out; always @(posedge clk) # delay out = in; endmodule module annotate; defparam top.m1.size = 5, // thay đổi tham số size của m1 top.m1.delay = 10, // thay đổi tham số delay của m1 top.m2.size = 10, // thay đổi tham số size của m2 top.m2.delay = 20; // thay đổi tham số delay của m2 endmodule Trong Ví dụ 3.22, module annotate có phát biểu defparam, giá trị từ phát biểu này sẽ đè lên những giá trị tham số size và delay trong instance m1 và m2 trong module top. Hai module top và annotate đều được xem như module top-level. 3.9.2.1.2.2 Phép gán giá trị tham số khi gọi instance của module Trong Verilog có một phương pháp khác dùng để gán giá trị đến một tham số bên trong instance của một module, đó là sử dụng một trong hai dạng của phép gán giá trị tham số trong instance của module. Một là phép gán theo thứ tự danh sách tham số, hai là phép gán bởi tên. Hai dạng phép gán này không thể đặt lẫn lộn với nhau mà chúng chỉ có thể là một trong hai [Type text] Page 87
  52. Giáo trình ngôn ngữ Verilog HDL dạng cho toàn bộ instance của module. Việc gán giá trị tham số instance của module theo thứ tự danh sách tham số, tương tự như việc gán giá trị trì hoãn cho những cổng của instance; còn việc gán giá trị tham số instance của module theo tên tham số, thì tương tự như việc kết nối port của module bởi tên. Nó gán những giá trị tham số cho những instance cụ thể mà trong module của những instance này đã định nghĩa những tham số trên. Một tham số mà đã được khai báo trong một block, một tác vụ hay một hàm chỉ có thể khai báo lại một cách trực tiếp dùng phát biểu defparam. Tuy nhiên, nếu giá trị tham số này phụ thuộc vào một tham số thứ hai, thì việc định nghĩa lại giá trị tham số thứ hai cũng sẽ cập nhật giá trị của tham số thứ nhất. Sau đây ta xét chi tiết hai phép gán tham số này. 1. Phép gán giá trị tham số theo thứ tự danh sách tham số Thứ tự của những phép gán trong phép gán giá trị tham số theo thứ tự danh sách tham số instance của module, sẽ theo thứ tự tham số lúc khai báo bên trong module. Nó không cần thiết phải gán giá trị cho tất cả các tham số có bên trong module khi dùng phương pháp này. Tuy nhiên, ta không thể nhảy qua một tham số, do đó để gán những giá trị cho một phần những tham số trong tất cả các tham số đã khai báo trong module, thì những phép gán để thay thế giá trị của một phần những tham số đó, sẽ đứng trước những khai báo của những tham số còn lại. Một phương pháp khác đó là phải gán giá trị cho tất cả các tham số nhưng dùng giá trị mặc định (cùng có giá trị như được gán trong khai báo tham số trong định nghĩa module) cho các tham số mà không cần có giá trị mới. Xét Ví dụ 3.24, trong ví dụ này những tham số bên trong instance của những module mod_a, mod_c, và mod_d được thay đổi trong khi gọi instance. Ví dụ 3.24 module tb1; wire [9:0] out_a, out_d; wire [4:0] out_b, out_c; reg [9:0] in_a, in_d; reg [4:0] in_b, in_c; reg clk; /* Bốn instance của module vdff với phép gán giá trị tham số theo thứ tự danh sách tham số*/ // mod_a có hai giá trị tham số mới size=10 và delay=15 [Type text] Page 88
  53. Giáo trình ngôn ngữ Verilog HDL vdff #(10,15) mod_a (.out(out_a), .in(in_a), .clk(clk)); // mod_b có giá trị tham số mặc định là (size=5, delay=1) vdff mod_b (.out(out_b), .in(in_b), .clk(clk)); // mod_c có một giá trị tham số mặc định là size=5 và một giá trị mới là delay=12 vdff #( 5,12) mod_c (.out(out_c), .in(in_c), .clk(clk)); */ Để thay đổi giá trị của tham số delay, ta cũng cần phải mô tả giá trị mặc định của tham số size*/ /* mod_d có một giá trị tham số mới là size=10, và giá trị tham số delay vẫn giữ giá trị mặc định của nó./* vdff #(10) mod_d (.out(out_d), .in(in_d), .clk(clk)); endmodule module vdff (out, in, clk); parameter size=5, delay=1; // tham số với giá trị mặc định output [size-1:0] out; input [size-1:0] in; input clk; reg [size-1:0] out; always @(posedge clk) #delay out = in; endmodule Những giá trị của tham số cục bộ (localparam) không thể bị đè lên, do đó chúng không được xem như là một phần thứ tự của danh sách cho phép gán giá trị tham số. Trong Ví dụ 3.25, addr_width sẽ được gán giá trị 12, và data_width sẽ được gán giá trị 16, mem_size sẽ không được gán giá trị một cách tường minh do thứ tự danh sách, nhưng nó sẽ có giá trị 4096 do biểu thức khai báo của nó. Ví dụ 3.25 module my_mem (addr, data); parameter addr_width = 16; //thứ tự tham số thứ nhất localparam mem_size = 1 << addr_width; parameter data_width = 8; //thứ tự tham số thứ hai [Type text] Page 89
  54. Giáo trình ngôn ngữ Verilog HDL endmodule module top; my_mem #(12, 16) m(addr,data); //không xét tham số localparram endmodule 2. Phép gán giá trị tham số bởi tên Phép gán giá trị tham số bởi tên bao gồm tên tường minh của tham số và giá trị mới của nó. Tên của tham số sẽ là tên được mô tả trong instance của module. Ta không cần thiết gán những giá trị đến tất cả các tham số bên trong module khi sử dụng phương pháp này. Chỉ những tham số nào mà được gán giá trị mới thì mới cần được chỉ ra. Biểu thức tham số có thể là một lựa chọn để việc gọi instance của module có thể ghi lại việc hiện diện của một tham số, mà không cần bất kì một phép gán đến nó. Những dấu đóng mở ngoặc được đòi hỏi, và trong trường hợp này tham số sẽ giữ giá trị mặc định của nó. Khi một tham số được gán một giá trị, thì một phép gán khác đến tên tham số này là không được phép. Xét Ví dụ 3.26, trong ví dụ này cả những tham số của mod_a và chỉ một tham số của mod_c và mod_d bị thay đổi trong khi gọi instance của module. Ví dụ 3.26 module tb2; wire [9:0] out_a, out_d; wire [4:0] out_b, out_c; reg [9:0] in_a, in_d; reg [4:0] in_b, in_c; reg clk; // Bốn instance của moduel vdff với giá trị tham số được gán bởi tên // mod_a có giá trị tham số mới là size=10 và delay=15 vdff #(.size(10),.delay(15)) mod_a (.out(out_a),.in(in_a),.clk(clk)); // mod_b có giá trị tham số mặc định là (size=5, delay=1) vdff mod_b (.out(out_b),.in(in_b),.clk(clk)); /* mod_c có một giá trị tham số mặc định là size=5 và có một giá trị tham số mới là delay=12*/ [Type text] Page 90
  55. Giáo trình ngôn ngữ Verilog HDL vdff #(.delay(12)) mod_c (.out(out_c),.in(in_c),.clk(clk)); /* mod_d có một giá trị tham số mới là size=10, còn tham số delay vẫn giữ giá trị mặc định*/ vdff #(.delay( ),.size(10)) mod_d (.out(out_d),.in(in_d),.clk(clk)); endmodule module vdff (out, in, clk); parameter size=5, delay=1; output [size-1:0] out; input [size-1:0] in; input clk; reg [size-1:0] out; always @(posedge clk) #delay out = in; endmodule Việc gọi những instance của module, dùng những loại định nghĩa lại tham số trong cùng module ở top-level thì hợp lệ. Xét trong ví dụ sau, những tham số của mod_a bị thay đổi bằng cách dùng việc định nghĩa lại tham số theo thứ tự danh sách; tham số thứ hai của mod_c được thay đổi bằng cách dùng việc định nghĩa lại tham số bằng tên, trong khi gọi instance của module. Ví dụ 3.27 module tb3; /* sự pha trộn giữa instance có khai báo tham số theo thứ tự và instance có khai báo tham số theo tên thì hợp lệ*/ vdff #(10, 15) mod_a (.out(out_a), .in(in_a), .clk(clk)); vdff mod_b (.out(out_b), .in(in_b), .clk(clk)); vdff #(.delay(12)) mod_c (.out(out_c), .in(in_c), .clk(clk)); endmodule Sẽ không hợp lệ khi gọi instace của bất kì module nào, dùng lẫn lộn những phép gán lại giá trị tham số bằng thứ tự danh sách tham số và tên, giống như trong phép gọi instance của module mod_a ở dưới đây: Ví dụ 3.28 // instance mod_a không hợp lệ do có sự pha trộn giữa các phép gán tham số [Type text] Page 91
  56. Giáo trình ngôn ngữ Verilog HDL vdff #(10, .delay(15)) mod_a (.out(out_a), .in(in_a), .clk(clk)); 3.9.2.1.3 Sự phụ thuộc tham số Một tham số (ví dụ, memory_size) có thể được định nghĩa với một biểu thức chứa những tham số khác (ví dụ, word_size). Tuy nhiên, việc gán đè giá trị tham số, có thể là bằng phát biểu defparam hoặc trong phát biểu gọi instance của module, sẽ thay thế một cách hiệu quả việc định nghĩa tham số với một biểu thức mới. Bởi vì memory_size phụ thuộc vào giá trị của word_size, bất kì có sự thay đổi nào của word_size sẽ làm thay đổi giá trị của memory_size. Ví dụ, trong khai báo tham số sau, một giá trị mới cập nhật của word_size, có thể là bởi phát biểu defparam hoặc phát biểu gọi instance của module mà trong module này đã định nghĩa những tham số trên, thì giá trị của memory_size sẽ được tự động cập nhật. Nếu memory_size được cập nhật bởi phát biểu defparam hay một phát biểu gọi instance thì nó sẽ lấy giá trị đó mà không cần quan tâm đến giá trị của word_size. Ví dụ 3.29 parameter word_size = 32, memory_size = word_size * 4096; 3.9.2.2 Tham số cục bộ (local parameter) Trong Verilog, tham số cục bộ (localparam) giống tương tự với tham số (parameter) ngoại trừ nó không thể được gán lại giá trị bởi phát biểu defparam, hoặc phép gán giá trị tham số khi gọi instance của module. Những tham số cục bộ (localparam) có thể được gán bởi những biểu thức hằng số chứa những tham số (parameter), mà những tham số (parameter) này có thể được gán lại giá trị bởi phát biểu defparam, hoặc phép gán giá trị tham số khi gọi instance của module. Việc chọn bit hay một phần của tham số cục bộ mà loại dữ liệu của nó không phải là real thì được phép. Ví dụ 3.30 localparam thamso1; localparam signed [3:0] thamso2; localparam time t1; localparam integer int2; localparam var = 5*6; 3.9.3 Tham số đặc tả (specify parameter) Từ khóa specparam khai báo nó là một loại đặc biệt của tham số (parameter) chỉ dùng cho [Type text] Page 92
  57. Giáo trình ngôn ngữ Verilog HDL mục đích cung cấp giá trị định thời (timing) và giá trị trì hoãn (delay), nhưng nó có thể xuất hiện trong bất kì biểu thức nào, với điều kiện biểu thức đó không được gán đến một tham số (parameter) và biểu thức đó cũng không phải là phần mô tả độ rộng trong một khai báo. Những tham số đặc tả (specparams) được phép khai báo bên trong khối đặc tả (specify block - là các khối bắt đầu bằng từ khóa specify endspecify) hoặc bên trong một module chính. Một tham số đặc tả (specify parameter) khai báo bên ngoài một khối đặc tả (specify block) thì cần được khai báo trước khi nó được sử dụng. Giá trị mà được gán đến một tham số đặc tả, có thể là một biểu thức hằng số bất kì. Một tham số đặc tả có thể được dùng như là phần của một biểu thức hằng số cho một khai báo tham số đặc tả kế tiếp. Không giống như một tham số module (module parameter), một tham số đặc tả không thể được gán lại giá trị từ bên trong ngôn ngữ Verilog, nhưng nó có thể được gán lại giá trị thông qua tập tin dữ liệu SDF (Standard Delay Format). Những tham số đặc tả (specify parameter) và tham số module (module parameter) không thể thay thế cho nhau. Ngoài ra, tham số module (module parameter) không thể được gán bởi một biểu thức hằng số mà có chứa tham số đặc tả (specify parameter). Bảng 3.4 tóm tắt sự khác nhau giữa hai loại khai báo tham số. Bảng 3.4 Sự khác nhau giữa hai loại khai báo tham số Specparams (tham số đặc tả) Parameters (tham số module) Sử dụng từ khóa specparam Sử dụng từ khóa parameter Cần được khai báo bên trong một module Cần được khai báo bên ngoài những khối hoặc một khối đặc tả (specify block) đặc tả (specify block) Có thể được dùng bên trong một module hoặc Không thể được dùng bên trong những một khối đặc tả (specify block) khối đặc tả (specify block). Có thể được gán bởi tham số đặc tả Không thể được gán bởi specparams. (specparam) và tham số module (parameter). Sử dụng tập tin dữ liệu SDF để gán đè giá trị Dùng phát biểu defparam hoặc phép gán cho tham số đặc tả. giá trị tham số cho instance của module để gán đè giá trị cho tham số. Một tham số đặc tả (specify parameter) có thể được mô tả độ rộng. Độ rộng của những tham số đặc tả cần tuân theo những qui luật sau:  Một khai báo tham số đặc tả mà không có mô tả độ rộng thì mặc định sẽ là độ rộng của giá trị cuối cùng được gán đến nó, sau khi có bất kì giá trị nào gán đè lên nó. Một khai báo tham số đặc tả mà có mô tả độ rộng thì độ rộng của nó sẽ theo độ rộng [Type text] Page 93
  58. Giáo trình ngôn ngữ Verilog HDL khai báo. Độ rộng sẽ không bị ảnh hưởng bởi bất kì giá trị nào được gán đè lên nó. Việc chọn bit hay một phần của tham số đặc tả mà loại dữ liệu của nó không phải là real thì được phép. Ví dụ 3.31 specify specparam trise_clk_q = 150, tFall_clk_q = 200; specparam trise_control = 40, tFall_control = 50; endspecify Trong ví dụ này, những dòng ở giữa những từ khóa specify và endspecify là để khai báo bốn tham số đặc tả. Dòng đầu tiên khai báo hai tham số đặc tả trise_clk_q và tFall_clk_q với giá trị tương ứng là 150 và 200. Dòng thứ hai khai báo hai tham số đặc tả trise_control và tFall_control với giá trị tương ứng là 40 và 50. Ví dụ 3.32 module RAM16GEN (output [7:0] DOUT, input [7:0] DIN, input [5:0] ADR, input WE, CE); specparam dhold = 1.0; specparam ddly = 1.0; parameter width = 1; parameter reg size = dhold + 1.0; /* Không hợp lệ - không thể gán tham số đặc tả (specparam) đến một tham số (parameter)*/ endmodule 3.10Bài tập 1. Trong ngôn ngữ mô tả phần cứng Verilog HDL, có mấy loại dữ liệu cơ bản? Nêu chức năng sử dụng của mỗi loại? 2. Trong kiểu dữ liệu net có những loại khai báo dữ liệu nào? Nêu sự khác nhau giữa các loại khai báo dữ liệu net ? 3. Trong kiểu dữ liệu biến có những loại khai báo dữ liệu nào? Nêu sự khác nhau giữa các loại khai báo dữ liệu biến? 4. Trong ngôn ngữ mô tả phần cứng Verilog HDL, có những loại tham số nào? Nêu sự khác biệt giữa tham số module và tham số đặc tả? 5. Khi nào ta sử dụng khai báo defparam? 6. Có mấy loại tham số module? Nêu sự khác biệt giữa hai khai báo parameter và localparam trong tham số module ? [Type text] Page 94