Thứ Hai, 11 tháng 11, 2019

[SV for Syn] Bài 1 – Những điểm mới của System Verilog khả tổng hợp

Chuỗi bài viết này sẽ trình bày về những thành phần mới của System Verilog (SV) so với Verilog trong mô tả RTL code khả tổng hợp. Tùy từng trường hợp cụ thể, những thành phần này sẽ góp phần giúp việc mô tả RTL code chính xác, hạn chế sai sót, đơn giản và dễ dàng hơn so với cách sử dụng Verilog thuần túy.
Bài viết đầu tiên sẽ cung cấp cho bạn đọc những điểm mới của ngôn ngữ SystemVerilog so với ngôn ngữ Verilog trong việc mô tả RTL code khả tổng hợp.
1) Lịch sử phát triển
SystemVerilog (SV) là chuẩn ngôn ngữ hợp nhất dành cho việc kiểm tra (verification), mô tả kỹ thuật (specification) và thiết kế (design) phần cứng. SV là một chuẩn được mở rộng từ chuẩn Verilog HDL giúp nâng cao khả năng mô tả thiết kế phần cứng và xây dựng thành phần kiểm tra.
Trong loạt bài viết này, tác giả chỉ tập trung vào các phần mở rộng được thêm vào SV so với Verilog. Cụ thể, tác giả sẽ trình bày các cấu trúc mới hỗ trợ mạnh cho việc mô hình hóa thiết kế. Thiết kế được hiểu là RTL code có thể tổng hợp được.
SV được phát triển với mục tiêu tạo ra một ngôn ngữ hợp nhất hỗ trợ cho cả thiết kế phần cứng, mô phỏng và mô tả hệ thống. SV là một chuẩn mở rộng từ Verilog và tích hợp thêm các thành phần từ C/C++. SV được phát triển lần đầu bởi tổ chức Accellera trước khi được chuẩn hóa bởi hiệp hội IEEE.
  • 12/12/1995: Verilog-1995 (IEEE Std 1364-1995 The Verilog Hardware Description Language (HDL) 
  • 28/9/2001: Verilog-2001 (IEEE Std 1364-2001 The Verilog Hardware Description Language (HDL) ) 
  • 6/2002: System Verilog 3.0 của Acceller 
  • 5/2003: System Verilog 3.1 của Accellera 
  • 4/2004: System Verilog 3.1a của Accellera 
  • 8/11/2005: System Verilog-2005 (IEEE 1800-2005 IEEE Standard for SystemVerilog--Unified Hardware Design, Specification, and Verification Language) 
  • 7/4/2006: Verilog-2005 (IEEE Std 1364-2005 The Verilog Hardware Description Language (HDL) 
  • 11/12/2009: System Verilog-2009 (IEEE 1800-2009 - IEEE Standard for SystemVerilog--Unified Hardware Design, Specification, and Verification Language) 
  • 21/9/2013: System Verilog-2012 (IEEE 1800-2012 - IEEE Standard for SystemVerilog--Unified Hardware Design, Specification, and Verification Language) 
  • 6/12/2017: System Verrilog-2017 (IEEE 1800-2017 - IEEE Standard for SystemVerilog--Unified Hardware Design, Specification, and Verification Language)
Hình 1: Lịch sử phát triển của SystemVerilog
2) Những điểm mới của SV hỗ trợ mô tả RTL code
Nội dung tiếp theo sẽ liệt kê một số điểm mới của có thể sử dụng để mô tả RTL code. Đồng thời, nhận xét về đặc điểm mới sẽ được nêu ra nhưng không được phân tích chi tiết trong bài viết này. Việc phân tích chi tiết từng thành phần với ví dụ cụ thể sẽ được trình bày trong các bài viết kế tiếp.
Hình 2: Một số điểm mới của SV so với Verilog
hỗ trợ mô tả RTL code khả tổng hợp
2.1 Giá trị không xác định kích thước (Unsized literal)
SV cho phép đặc tả một giá trị có kích thước không xác định mà không cần kèm cơ số. Cơ số là ký hiệu chỉ định giá trị là số thập phân, số hex, số octal hoặc số binary. Giá trị này gồm một dấu nháy đơn đứng trước giá trị một bit.

'0, '1, 'X, 'x, 'Z, 'z

Khi một biến được gán đến giá trị này, tất cả các bit trong biến đó sẽ có cùng giá trị đã được mô tả.
Ví dụ 1:
reg [7:0] a;
a= 8'b11111111;
sẽ tương đương với:
reg [7:0] a;
a= '1;
2.2 Kiểu dữ liệu (Data types)
2.2.1 Kiểu dữ liệu logic, bit, int, byte, shortint, longint
Trong đó:
  • logic là kiểu dữ liệu 4 trạng thái
  • bit, int, byte, shortintlongint là các kiểu dữ liệu 2 trạng thái
Các kiểu dữ liệu 4 trạng thái và 2 trạng thái đã liệt kê trên đầy đều có thể tổng hợp được. Tuy nhiên, kiểu dữ liệu 2 trạng thái sẽ hạn chế dùng để mô tả RTL code vì:
  • Có thể gây sai lệch kết quả mô phỏng giữa RTL code và gate netlist.
  • Có thể gây ra các bug (lỗi) tiềm tàng không thể được phát hiện sớm
2.2.2 Kiểu dữ liệu người dùng tự định nghĩa (user-defined type)
SystemVerilog cho phép người dùng tự định nghĩa 1 kiểu dữ liệu mới từ những kiểu dữ liệu đã tồn tại. Điều này giúp mở rộng kiểu dữ liệu và tái sử dụng các cấu trúc dữ liệu của người dùng dễ dàng. Bên cạnh đó, RTL code có thể tường minh và dễ đọc hơn khi người mô tả code có thể định nghĩa một kiểu dữ liệu với tên gọi gợi nhớ mục đích sử dụng.

2.2.3 Kiểu dữ liệu Structure (struct) và Union (union)

struct union cho phép đóng gói (tập hợp) nhiều đối tượng dữ liệu (data object) có kiểu khác hoặc giống nhau trong một đối tượng (object) hoặc kiểu dữ liệu (data type). Các đối tượng dữ liệu được tập hợp trong một struct hoặc union thường có mối liên quan với nhau khi sử dụng trong một thiết kế.
Trong khi các đối tượng dữ liệu trong một struct có thể được sử dụng song song cùng một thời điểm thì union chỉ cho phép sử dụng một thành phần dữ liệu tại một thời điểm.


2.2.4 Kiểu liệt kê (enumerated type)

Kiểu liệt kê cho phép khai báo một danh sách các giá trị hợp lệ (các hằng số) khác nhau với tên riêng do người dùng định nghĩa, gọi là nhãn (label). Điều này giúp giảm rủi ro và sai sót khi mô tả hằng số trong RTL code trên các phương diện sau: 
  • Hạn chế khai báo sai giá trị khi cần khai báo một danh sách các hằng số có giá trị phân biệt nhau. 
  • Phát hiện lỗi sớm khi khai báo các hằng số trùng nhau. Cũng như cách khai báo dùng parameter `define, kiểu liệt kê cũng giúp RTL code dễ đọc hơn vì các giá trị được truy xuất bằng tên gợi nhớ do người dùng đặt.
2.2.5 Kiểu dữ liệu void
Verilog không hỗ trợ kiểu dữ liệu void. Trong Verilog, các function phải trả về một giá trị và giá trị này được gán cho tên function khi function được gọi. Điều này làm cho function trong Verilog chỉ dùng để mô hình hóa mạch tổ hợp với một ngõ ra duy nhất ứng với kiểu dữ liệu và độ rộng bit của tên function. SV hỗ trợ thêm loại dữ liệu void. Loại này biểu thị ý nghĩa “dữ liệu không tồn tại”. Loại dữ liệu này sử dụng cùng với định nghĩa function để chỉ ra một function không có giá trị trả về. Nghĩa là, không có giá trị nào được gán cho tên function.

Ví dụ 2:
function void example (
//Ports declaration );
//Code
endfunction
Trong RTL code khả tổng hợp, một void function được sử dụng kết hợp với các khai báo input, output, inout để mô hình các mạch logic một cách linh động với nhiều ngõ vào và ngõ ra khác nhau.

2.3 Ép kiểu (casting)
Verilog 1995 không hỗ trợ ép kiểu dữ liệu. Trong các phiên bản sau, Verilog hỗ trợ thêm việc chuyển đổi qua lại giữa các giá trị có dấu và không dấu sử dụng hai chức năng hệ thống là $signed$unsigned.
SV hỗ trợ chuyển kiểu dữ liệu của một hằng số hoặc biểu thức từ kiểu dữ liệu hiện tại sang kiểu dữ liệu khác, gọi là ép kiểu. SV hỗ hai loại ép kiểu là ép kiểu tĩnh (static cast) và ép kiểu động (dynamic cast). Trong đó chỉ có ép kiểu tĩnh là có thể tổng hợp được.
Trong một số trường hợp, ép kiểu giúp giảm số lượng các thông điệp cảnh báo (warning) ở các phần mềm kiểm tra RTL code hoặc tổng hợp.

2.4 Gán theo mẫu dữ liệu
SV định nghĩa thêm một ký hiệu mới là ‘{} ( khác với toán tử ghép bit {}) để tạo ra các mẫu dữ liệu dùng cho việc gán, gọi tắt là “mẫu gán” (assignment pattern) cho đối tượng có kiểu dữ liệu struct hoặc mảng. “Mẫu gán” là một nhóm các hằng số hoặc biểu thức hằng. Các hằng số hoặc biểu thức hằng trong “mẫu gán” sẽ được gán đến các thành phần của đối tượng kiểu struct hoặc mảng.
Ví dụ 3:
typedef struct {int a; shortreal b;} ab;
ab c;
c = '{0, 0.0};
ab abarr[1:0] = '{'{1, 1.0}, '{2, 2.0}};
Trong ví dụ trên, c là đối tượng có kiểu dữ liệu người dùng tự định nghĩa (user-defined type) ab, abarr là một mảng có kiểu dữ liệu ab. Phép gán đầu tiên sẽ gán giá trị cho các thành phần trong c như sau:
c.a = 0 
c.b = 0.0
Phép gán thứ 2 sẽ gán giá trị cho các thành phần trong mảng abarr như sau:
abarr[1].a = 1
abarr[1].b = 1.0
abarr[0].a = 2
abarr[0].b = 2.0
2.5 Mở rộng định nghĩa mảng
Verilog hiện hỗ trợ định nghĩa mảng có thể tổng hợp được với nhiều giới hạn về loại dữ liệu và cách sử dụng. SV mở rộng khả năng sử dụng và tổng hợp của mảng bằng cách phân biệt thành hai loại:
Mảng đóng gói (packed array): là một cơ chế giúp chia nhỏ một vector thành các nhóm bit, gọi là các trường con (subfield). Một mảng đóng gói vẫn được sử dụng như một vector. Loại mảng này dùng để mô hình một vector có nhiều trường riêng biệt.

Ví dụ 4: packed array
logic [3:0] [7:0] data; // mảng đóng gói 2 chiều 32-bit

Mảng không đóng gói (unpacked array): là mảng được khai báo tương tự như mảng trong Verilog như sau:
<data_type> <vector_size> <array_name> <array_dimensions>
Trong đó:
  • <data_type> là kiểu dữ liệu
  • <vector_size> là kích thước của một phần tử trong mảng
  • <array_name> là tên mảng
  • <array_dimensions> là kích thước các chiều của mảng
Ví dụ 5: unpacked array
reg [7:0] RAM [0:4905];
Mỗi phần tử trong mảng không đóng gói là độc lập với nhau. Loại mảng này chủ yếu được sử dụng để mô hình bộ nhớ. SV chỉ mở rộng thêm các loại dữ liệu mới có thể dùng để khai báo mảng này như logic, bit, byte, int, longint, struct, enum và các kiểu người dùng định nghĩa. 
Bên cạnh đó, SV còn hỗ trợ các chức năng hệ thống giúp truy vấn nhanh thông tin mảng như $size, $left, $right, $low, $high, $increment, $dimensions, $unpacked_dimensions.

2.6 Toán tử mới
SV thêm vào các toán tử mới cho phép mô hình hóa code RTL khả tổng hợp ngắn gọn, súc tích hơn như:
  • Toán tử tăng, giảm: ++, --
  • Toán tử gán: +=, -=, *=, /=, %=, <<=, >>=, <<<=, >>>=
  • Toán tử so sánh: ==?, !=?
  • Việc hỗ trợ các toán tử mới giúp việc mô tả RTL code linh động hơn và ngắn gọn hơn trong một số trường hợp cụ thể.
2.7 Toán tử inside, if-inside và case-inside
Toán tử inside có tên gọi khác là “set membership operator” cho phép kiểm tra một giá trị có thuộc tập giá trị đã cho hay không. Nếu giá trị cần kiểm tra thuộc tập đã cho, giá trị TRUE được trả về. Nếu giá trị cần kiểm tra không thuộc tập đã cho, giá trị FALSE được trả về. 
Toán tử này giúp việc mô tả RTL code ngắn gọn khi cần so sánh một biến hoặc biểu thức với nhiều giá trị khác nhau. 
Bên cạnh đó, việc dùng inside kết hợp với case có ưu điểm hơn so với dùng casex hoặc casez.

2.8 Các từ khóa bổ nghĩa unique và priority
SV bổ sung thêm các từ khóa bổ nghĩa unique priority để dùng chung với các phát biểu thủ tục if-elsecase. Các từ khóa này giúp người thiết kế mô tả tường minh hành vi của mạch logic khi dùng if-else hoặc case. Các phần mềm như trình mô phỏng và trình tổng hợp phải hỗ trợ thực thi thêm các kiểm tra đã được SV quy định để cảnh báo người thiết kế những nguy hiểm tiềm tàng. Điều này giúp hạn chế các sai sót khi mô tả RTL code dùng if-else hoặc case.

2.9 Tên khối sau các từ khóa end
SV hỗ trợ thêm việc thêm tên khối (block name) sau các từ khóa end như endmodule, endinterface, endtask, endfunctionend trong một khối begin-end.
Điều này giúp việc đọc RTL code dễ dàng hơn vì nó giúp xác định rõ điểm kết thúc của một khối.
Ví dụ 6:
module example ();
  …
  always_comb begin: next_state
    …
  end : next_state
  …
endmodule : example
Trong ví dụ trên tên next_state giúp xác định dòng RTL code bắt đầu và dòng RTL code kết thúc của khối begin-end. Tên example giúp xác định dòng RTL bắt đầu và dòng RTL code kết thúc của một module.

2.10 Khối thủ tục tường minh
SV thêm vào 3 khối thủ tục tường minh là always_comb, always_latch, always_ff giúp việc mô hình các mạch tổ hợp và tuần tự chính xác, ít lỗi hơn so với việc dùng always. Điều này đạt được bởi vì các phần mềm kiểm tra, mô phỏng và tổng hợp RTL code phải thực hiện thêm các điều kiện kiểm tra được quy định riêng cho always_comb, always_latchalways_ff để cảnh báo cho người viết code khi có vi phạm. 
Các quy định riêng khi dùng các khối thủ tục tường minh giúp loại bỏ những sai sót có thể gặp phải khi dùng always.

2.11 Nâng cấp đặc điểm của task và function
SV cải tiến khả năng sử dụng của task function để giúp mở rộng khả năng ứng dụng của hai thành phần này. Các đặc điểm được cải tiến bao gồm: 
  • void function 
  • Cho phép khai báo outputinout trong function 
  • Mở rộng loại dữ liệu làm đối số cho task/function 
  • Mở rộng loại dữ liệu trả về cho function 
  • Kết nối các đối số theo tên khi gọi task/function 
  • Hỗ trợ từ khóa return để mô tả giá trị trả về trong function 
2.12 Phương pháp mới để mô tả kết nối
SV hỗ trợ thêm các cách mới giúp kết nối các tín hiệu của instance là:
.<port_name>


.*

Đây là các cách kết nối “ngầm hiểu” (implicit).

2.13 Định nghĩa interface
SV cho phép gom nhóm nhiều tín hiệu thành một giao tiếp, gọi là một interface. Một interface sẽ được định nghĩa bởi cặp từ khóa interface/endinterface. Định nghĩa interface giúp giảm số lượng RTL code trong việc khai báo danh sách port của module và kết nối các instance.

2.14 do…while loop 
SV thêm một vòng lặp mới có thể tổng hợp là do…while. Điều kiện của vòng lặp do…while được kiểm tra ở cuối vòng lặp thay vì kiểm tra ở đầu vòng lặp như vòng lặp while. Điều này đảm bảo vòng lặp được thực thi ít nhất một lần và làm cho các biến bị gán trong vòng lặp sẽ được khởi tạo đến một giá trị. 

2.15 Package 
SV hỗ định nghĩa package giúp chia sẻ các tham số (parameter), các kiểu dữ liệu, taskfunction giữa các module interface. Package được dùng để đóng gói các thành phần cấu trúc chung. Các thành phần này thường được sử dụng lặp đi lặp lại nhiều lần trong cùng một thiết kế hoặc nhiều thiết kế khác nhau trong cùng một dự án. Việc sử dụng package còn giúp tăng khả năng tái sử dụng (reuse) các thành phần qua nhiều dự án khác nhau. 
3 )Tóm tắt
Bài viết chỉ trình bày mức tổng quan các thành phần mới có thể sử dụng trong việc mô tả RTL code khả tổng hợp chứ chưa tập trung phân tích chi tiết. 
Phân tích chi tiết của các thành phần mới sẽ được trình bày cụ thể trong những bài viết sau.

Lịch sử cập nhật:
1) 2019.11.10 - Tạo lần đầu 

Tài liệu tham khảo:
1. Design Automation Standards Committee, IEEE Computer Society; IEEE Standard for SystemVerilog - Unified Hardware Design, Specification, and Verification Language; December, 06, 2017.
2. Synopsys; HDL Compiler for SystemVerilog User Guider; March 2012.
3. Stuart Sutherland; Modeling with SystemVerilog in a Synopsys Synthesis Design Flow Using Leda, VCS, Design Compiler and Formality; 2006.
4. Stuart Sutherland, Don Mills; Synthesizing SystemVerilog Busting the Myth that SystemVerilog is only for Verification; 2013.
5. Synopsys; Synopsys Synplify Pro for Microsemi Edition – Language Support Reference; November, 2016
6. Stuart Sutherland, Simon Davidmann, Peter Flake; A Guide to Using SystemVerilog for Hardware Design and Modeling; 2006.

2 bình luận:

  1. Hi ad, mình không tìm thấy các bài phân tích chi tiết về các thành phần SV đã nêu trong bài viết này

    Trả lờiXóa
    Trả lời
    1. Hiện chuỗi bài này chỉ mới có bài 1, chưa có các bài phân tích chi tiết. Vì đội ngũ thực hiện đều đang đi làm và đi học nên việc chia sẻ phụ thuộc vào tình hình thực tế.

      Xóa