Chủ Nhật, 26 tháng 1, 2020

[SV for Syn] Bài 2- Giá trị không xác định kích thước (unsized literal)

Tiếp theo bài 1, bài viết này sẽ phân tích chi tiết về giá trị (số) không xác định kích thước (unsized literal value/number) trong System Verilog (SV). Đồng thời, chúng sẽ được so sánh với Verilog HDL để làm rõ các ưu nhược điểm khi dùng để mô tả RTL code.

Danh sách bài viết liên quan:
Bài 1: Những điểm mới của System Verilog khả tổng hợp

1) Khái niệm literal
Literal, còn gọi là literal constant, là giá trị thể hiện chính nó. Literal là một giá trị cố định, không thay đổi.
Ví dụ, số 8 là một literal đại diện cho chính nó và chỉ thể hiện một giá trị là 8, không thể là 9 hay bất kỳ ý nghĩa nào khác. 8 là một literal nguyên trong SV. Một ví dụ khác, chuỗi ký tự “good” là một literal chuỗi trong SV.
Literal còn được gọi là literal constant nhưng nó không phải là hằng số (constant). Nghĩa là literal constant hay literal là khác với constant. Constant là đối tượng dữ liệu được định danh theo tên (named data object). Trong SV, một hằng số có thể được khai báo bằng parameter, localparam, specparam hoặc const.
Ví dụ 1: Phân biệt literal và hằng số (constant)
parameter WIDTH = 32;
Trong ví dụ trên, WIDTH là một hằng số còn 32 là một literal. 32 luôn là 32 còn WIDTH có thể được gán giá trị lại bằng một literal khác.
2) Phân loại literal
SV chia literal thành các nhóm sau:
  • Số (number):
    • Literal nguyên (integer literal constant) có thể được biểu diễn dưới dạng thập phân (decimal), thập lục phân (hexadecimal), bát phân (octal) hoặc nhị phân (binary)
    • Literal thực (real literal constant) được biểu diễn theo chuẩn IEEE Std 754 về số dấu chấm động có độ chính xác kép.
  • Literal thời gian (time literal) là một giá trị realtime được tỷ lệ theo đơn vị thời gian (fs, ps, ns, us, ms, s) hiện tại và được làm tròn theo sai số thời gian hiện tại  
  • Literal chuỗi (string literal) là một chuỗi ký tự đặt trong cặp dấu ngoặc kép, “ ”, các ký tự không thể in được và ký tự đặc biệt sẽ đi kèm dấu “\” đằng trước 
  • Literal cấu trúc (structure literal) là các mẫu gán hoặc biểu thức cấu trúc với các thành phần là hằng số.
  • Literal mảng (arrayliteral) là các mẫu gán hoặc biểu thức mảng với các thành phần là hằng số.
Ví dụ 2: Minh họa các loại literal
8’h9a //literal nguyên
1.30e-2 //literal thực
2.1ps //literal thời gian
“Hello word\n” //literal chuỗi 
typedef struct {int a; shortreal b;} ab;
ab c; 
c = '{0, 0.0}; //literal cấu trúc
int n[1:2][1:3] = '{'{0,1,2},'{3{4}}}; //literal mảng
Trong ví dụ trên,
  • 2.1ps là một literal thời gian có giá trị là 2.1 và đơn vị là ps
  • “Hello world\n”, không bao gồm dấu ngoặc kép, là literal chuỗi. Trong đó, “\n” là ký tự xuống dòng
  • ‘{0, 0.0} là một literal cấu trúc được dùng để gán giá trị cho biến c được định nghĩa bởi kiểu dữ liệu struct ab.
  • '{'{0,1,2},'{3{4}}} là một literal mảng dùng để gán giá trị cho các phần tử có kiểu dữ liệu là int trong mảng n.
3) Giá trị không xác định kích thước
Một giá trị không xác định kích thước là một giá trị nguyên, thuộc integer literal, là một giá trị không được xác định rõ số bit biểu diễn giá trị. Một giá trị không xác định kích thước có thể là một trong hai dạng sau:
  • Một số thập thân đơn thuần (simple decimal number).
  • Một số nguyên được biểu diễn dưới dạng <size><base><value> nhưng thiếu trường <size>
Ví dụ 3: Giá trị không xác định kích thước
9 //số thập phân đơn thuần
‘h8 //số nguyên thiếu mô tả độ rộng bit
Trong ví dụ trên, 9 là một số thập phân đơn thuần, giá trị này không chỉ rõ số bit biểu diễn nó là bao nhiêu. Nó khác với cách biểu diễn 8’d9. Ở cách biểu diễn này, giá trị 9 được chỉ rõ được biểu diễn bằng 8 bit.
‘h8 là một giá trị thập lục phân nhưng khuyết trường <size> nên cũng không thể xác định cụ thể số bit biểu diễn giá trị này là bao nhiêu.
Cả Verilog HDL và SV đều hỗ trợ biểu diễn số không xác định kích thước. Nó được gọi là unsized number, hoặc unsized literal constant, hoặc unsized literal hoặc unsized literal value.
4) Số không xác định kích thước trong Verilog
Nội dung của mục này căn cứ trên phiên bản Verilog 2005.
Verilog HDL, không định nghĩa rõ ràng khái niệm literal. Khái niệm được sử dụng là số (number). Number được trình bày ở mục “3.5 Numbers” và được định nghĩa bằng syntax 3-1. Một số trong Verilog có thể là số thập phân, số bát phần, số thập lục phân, số nhị phân hoặc số thực.
number ::=decimal_number| octal_number| binary_number| hex_number| real_number  
Số không xác định kích thước thường dùng trong các trường hợp sau:
  • Gán đến một tín hiệu hoặc hằng số có kích thước (độ rộng bit) thay đổi
  • Gán cùng một giá trị (0, x hoặc z) đến tất cả các bit trong một tín hiệu hoặc hằng số
Ví dụ 4: Gán giá trị không xác định kích thước
reg [WIDTH-1:0] regData;
regData = 9; //Gán bằng 9
regData = ‘b0; //Gán tất cả các bit bằng 0
regData = ‘bx; //Gán tất cả các bit bằng x
regData = ‘hx9; //Gán 4 bit cuối là 1001, các bit khác là x
regData = ‘bz; //Gán tất cả các bit bằng z
regData = ‘hz8; //Gán 4 bit cuối là 1000, các bit khác là z
regData = ‘b1; //Gán bit 0 bằng 1 và các bit khác bằng 0
Trong ví dụ trên, regData là một tín hiệu có độ rộng bit thay đổi theo giá trị WIDTH. Độ rộng này được gán một lần trước khi biên dịch hoặc tổng hợp code. Giả sử động rộng bit là 16 bit. thì kết quả các phép gán theo thứ tự như sau:
# --- regData = 0000000000001001
# --- regData = 0000000000000000
# --- regData = xxxxxxxxxxxxxxxx
# --- regData =   xxxxxxxxxxxx1001
# --- regData =   zzzzzzzzzzzzzzzz
# --- regData =   zzzzzzzzzzzz1000
# --- regData = 0000000000000001
Trong đó:
  • Phép gán thứ 1, dù độ rộng bit là bao nhiêu thì regData cũng được gán bằng 9
  • Phép gán thứ 2,  dù độ rộng bit là bao nhiêu thì tất cả các bit của regData đều được gán bằng 0
  • Phép gán thứ 3,  dù độ rộng bit là bao nhiêu thì tất cả các bit của regData đều được gán bằng x
  • Phép gán thứ 4,  bốn bit cuối sẽ được gán bằng 9 vì biểu diễn kiểu hex còn tất cả các bit cao đều được gán bằng x
  • Phép gán thứ 5,  dù độ rộng bit là bao nhiêu thì tất cả các bit của regData đều được gán bằng z
  • Phép gán thứ 6,  bốn bit cuối sẽ được gán bằng 8 vì biểu diễn kiểu hex còn tất cả các bit cao đều được gán bằng z
  • Phép gán thứ 7,  chỉ 1 bit cuối sẽ được gán bằng 1 vì biểu diễn kiểu binary còn tất cả các bit cao đều được gán bằng 0
Việc gán giá trị được dựa trên nguyên tắc như sau:
  • Đối với số thập phân đơn thuần thì tất cả các bit được gán phải thể hiện đúng giá trị số thập phân
  • Đối với dạng biểu diễn <base><value>, ví dụ ‘b0, nguyên tắc mở rộng bit được áp dụng như sau:
    • x nếu bit ngoài cùng bên trái của value là x
    • z nếu bit ngoài cùng bên trái của value là z
    • 0 nếu ngoài 2 trường hợp trên
Verilog không hỗ trợ việc mô tả một số không xác định kích thước giúp gán tất cả các bit của một tín hiệu bằng 1. Để gán tất cả các bit của một tín hiệu, có độ rộng thay đổi, bằng 1 trong Verilog, hai cách sau có thể sử dụng:
  • Mô tả giá trị toàn bit 1 với độ rộng cụ thể đối với từng trường hợp
  • Dùng toán tử lặp (replication) “{{}}
  • Dùng toán tử bù bitwise (Bitwise negation) ~
Ví dụ 5: Các cách gán 1 đến tất cả các bit của một tín hiệu có giá trị thay đổi
parameter WIDTH = 16;
reg [WIDTH-1:0] regData;
regData = 16'hffff; //Mô tả đúng độ rộng bit
regData = {WIDTH{1'b1}}; //Dùng toán tử lặp
regData = ~0; //Dùng toán tử bù bitwise
Ví dụ trên là một số cách có thể áp dụng để gán giá trị toàn bit 1 đến một tín hiệu.
  • Cách thứ 1 phải chỉ rõ độ rộng bit của tín hiệu regData. Bất lợi lớn nhất của cách này là khi độ rộng bit tín hiệu thay đổi thì trường <size> của giá trị cũng phải thay đổi theo
  • Cách thứ 2 phải biết hằng số khai báo độ rộng WIDTH của tín hiệu regData.
  • Cách thứ 3 là một "mẹo" viết code
Tóm lại, việc gán cùng một giá trị 0, 1, x hoặc z đến tất cả các bit của một tín hiệu có thể thực hiện trên Verilog nhưng thông qua các cách “cần phải nhớ nguyên tắc và thủ thuật”. Trong các ví dụ đã trình bày, việc này đạt được thông qua cơ chế mở rộng bit hoặc dùng các toán tử khác kèm theo hoặc phải chỉ rõ độ rộng bit.
5) Số không xác định kích thước trong System Verilog
SV định nghĩa rõ ràng khái niệm literal. Trong SV 2017, khái niệm này định nghĩa trong mục “5.7 Numbers”. Tuy SV vẫn bắt đầu với khái niệm number nhưng căn cứ theo cú pháp "Syntax 5-2" thì number chỉ là một phần của literal.
primary_literal ::= number | time_literal | unbased_unsized_literal | string_literal
Trong đó, number bao gồm literal nguyên và literal thực, ứng với số nguyên (integer number) và số thực (real number) trong Verrilog.
Một điểm chú ý khác là, tuy tên của “syntax 5-2” là “Syntax for integer and real numbers” giống với “syntax 3-1” trong Verilog nhưng SV đã định nghĩa lại các điểm sau:
  • syntax 5-2 định nghĩa primary_literal đã bao gồm cả syntax 3-1 định nghĩa number
  • syntax 5-2 bổ sung thêm time_literal, unbased_unsized_literal string_literal
Như vậy, việc sử dụng tên cũ là “Syntax for integer and real numbers” trong SV dễ gây hiểm nhầm là literal chỉ gồm số nguyên và số thực. Bạn đọc cần chú ý điểm này khi đọc tài liệu SV.
Hình 1: Khái niệm số (number) trong Verilog (trái) và khái niệm literal trong SV (phải)
Ngoài các đặc điểm đã về số không xác định kích thước như Verilog. SV đã nâng cấp để hỗ trợ thêm loại giá trị không xác định kích thước (unsized) và không xác định cơ số (unbased), gọi là unbased unsized literal. Loại này là một giá trị đơn bit (single bit). Nó được dùng để thiết lập cùng một giá trị cho tất cả các bit của tín hiệu hoặc hằng số.
Ví dụ 6: Loại số không xác định kích thước và cơ số
‘0 //Gán 0 đến tất cả các bit được gán bên vế trái
‘1 //Gán 1 đến tất cả các bit được gán bên vế trái
‘x //Gán x (unknown) đến tất cả các bit được gán bên vế trái
‘X //Gán x (unknown) đến tất cả các bit được gán bên vế trái
‘z //Gán z (high-impedance) đến tất cả các bit được gán bên vế trái
‘Z //Gán z (high-impedance) đến tất cả các bit được gán bên vế trái
Chú ý, dấu nháy được sử dụng là dấu apostrophe, còn gọi là tick, nằm cạnh phím enter trên bàn phím chứ không phải dấu back tick, nằm cạnh số 1 trên bàn phím.
Ví dụ 7: Gán giá trị không xác định kích thước và cơ số
parameter WIDTH = 64;
reg [WIDTH-1:0] regData;
initial begin
  regData = '0;
  $display("--- regData = %b", regData);
  //
  regData = '1;
  $display("--- regData = %b", regData);
  //
  regData = 'x;
  $display("--- regData = %b", regData);
  //
  regData = 'z;
  $display("--- regData = %b", regData);
end
Kết quả của ví dụ trên đây:
# --- regData = 000000000000
# --- regData = 111111111111
# --- regData = xxxxxxxxxxxx
# --- regData = zzzzzzzzzzzz
Với nâng cấp mới này, khi cần gán một giá trị toàn bit 0, 1, x hoặc z đến một tín hiệu trong SV, chúng ta không cần “nhớ” xem tín hiệu này bao nhiêu bit, không cần mô tả kích thước và cơ số. Đặc biệt, trường hợp gán toàn bit 1 sẽ không cần dùng thêm toán tử như Verilog.
Hình 2: Số không xác định kích thước trong Verilog (trái) được mở rộng thêm trong SV (phải)

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

Tài liệu tham khảo:
1.  IEEE Computer Society and  IEEE Standards Association Corporate Advisory Group;  IEEE Standard for SystemVerilog—  Unified Hardware Design,  Specification, and Verification  Language; 06.Dec.2017
2. IEEE Computer Society  IEEE Standard for Verilog® Hardware Description Language,  Specification, and Verification  Language; 07.Apr.2006
3. Stuart Sutherland, Simon Davidmann, Peter Flake; A Guide to Using SystemVerilog for Hardware Design and Modeling; 2006.
5. Synopsys; HDL Compiler for SystemVerilog User Guider; March 2012.
6. Thiết kế vi mạch số với VHDL & Verilog-Tống Văn On.

0 bình luận:

Đăng nhận xét