# 3. SystemVerilog Data Type
## SystemVerilog Data Types Overview
* SystemVerilog 是 Verilog 的擴充版本,除了可作為硬體描述語言(HDL),也提供更多支援 驗證工作的資料型別。
* Verilog 僅有基本的 reg 與 wire,這在面對日益複雜的測試環境時不夠靈活。
* 為了讓驗證程式更簡潔與易管理,SystemVerilog 加入了許多類似 C 語言的資料型別,例如:
* byte, shortint, int, longint, logic, bit
* 這些型別提供:
* 更好的 封裝能力
* 更簡潔、易讀的程式碼結構
* 支援更高層次的行為建模與測試
### 🔷 SystemVerilog
| Data-type | 2-state / 4-state | # Bits | signed/unsigned | C equivalent |
|-----------|-------------------|--------|------------------|--------------|
| reg | 4-state | >= 1 | unsigned | |
| wire | 4-state | >= 1 | unsigned | |
| integer | 4-state | 32 | signed | |
| real | - | - | - | double |
| time | - | - | - | |
| realtime | - | - | - | double |
---
### 🟣 Verilog
| Data-type | 2-state / 4-state | # Bits | signed/unsigned | C equivalent |
|------------|-------------------|--------|------------------|--------------|
| logic | 4-state | >= 1 | unsigned | |
| bit | 2-state | >= 1 | unsigned | |
| byte | 2-state | 8 | signed | char |
| shortint | 2-state | 16 | signed | short int |
| int | 2-state | 32 | signed | int |
| longint | 2-state | 64 | signed | long int |
| shortreal | - | - | - | float |
## Comments
* 單行註解:使用 //,該行從此符號開始後的部分都會被視為註解。
```
// 這是一行註解
```
多行註解(區塊註解):使用 /* ... */ 包住多行內容。
```
/* 這是
多行註解 */
```
* 注意事項:
* 可以在多行註解內嵌入單行註解(//)
* 不能將一個多行註解 /* */ 寫在另一個多行註解內部 → 語法錯誤
## Value System
| State | Description |
|-----------|-----------------------------------------------------------------------------|
| 0 | Logic state 0 - variable/net is at 0 volts |
| 1 | Logic state 1 - variable/net is at some value > 0.7 volts |
| x or X | Logic state X - variable/net has either 0/1 - we just don't know |
| z or Z | Logic state Z - net has high impedance - maybe the wire is not connected and is floating |
## SystemVerilog 的增強型 ' 常數表示法
* 在 Verilog 中,可以使用 '0、'Z、'X 來填滿整個向量的所有位元,但無法直接使用 '1 來達成:
```
m_var = 'h1; // 只會設 LSB,結果為 8'b00000001
```
* 若要填滿 1,Verilog 需透過concatenation(串接運算)方式:
```
m_var = {WIDTH{1'b1}};
```
* 在 SystemVerilog 中,這問題被解決,支援:
* '1 → 自動填滿所有位元為 1
* '0、'Z、'X 依然可用
* 不需指定進位基底(binary、hex 等)
* 注意:不可以寫成 'F0 或 'cafe,這會造成語法錯誤,因為 SystemVerilog 要求這種情況必須加上進位格式說明(如 8'hF0)
## 浮點數與科學記號格式
* SystemVerilog 使用 real 型別來儲存 浮點數(floating point)。
* 支援 指數表示法(exponential notation),例如 1e6 表示 1,000,000。
* real 可儲存像 3.14、7.2e6 等數值。
* 顯示輸出時的格式化方式:
* %f:預設浮點格式(6 位小數)
* %0.3f:顯示 3 位小數
* %0d:當作整數格式輸出(注意會帶有 .000000)
```
module tb;
real pi;
real freq;
initial begin
pi = 3.14;
freq = 1e6;
$display("Value of pi = %f", pi); // 顯示 3.140000
$display("Value of pi = %0.3f", pi); // 顯示 3.140
$display("Value of freq = %0d", freq); // 顯示 1000000.000000
end
endmodule
```
## String
* 字串可跨行撰寫,但輸出結果仍會是單行(沒有換行):
```
$display("New York is an awesome place.
So energetic and vibrant.");
// 輸出:New York is an awesome place.So energetic and vibrant.
```
* 若要輸出真正的多行文字,可在字串中插入 \n(換行符號):
```
$display("New York is an awesome place.\n
So energetic and vibrant.");
```
* 輸出結果:
```
New York is an awesome place.
So energetic and vibrant.
```
* 單一字元儲存:
* "D" 可儲存在 byte(8 位元)
* "\n" 可儲存在 bit [7:0]
* 字串儲存方式:
* "Hello World" 含 11 個字元 → 共需 88 bits(每字元 8 bits)
* 可用以下方式儲存:
* bit [8*11:1] myMessage
* string myMessage2(使用動態配置)
## Structures
* Structure(結構) 可以把多種不同型別的資料封裝在一起,以同一變數名稱來操作。
* 使用 typedef struct { ... } 定義結構型別,像 C 的 struct。
* 結構變數可以:
* 直接依順序指定值
* 使用欄位名稱指定值
* 使用 default 設定所有欄位
* 依欄位型別統一賦值
```
// 定義結構型別
typedef struct {
int coins;
real dollars;
} s_money;
// 宣告變數
s_money wallet;
// 各種指派方式
wallet = '{5, 19.75}; // 順序指派
wallet = '{coins:5, dollars:19.75}; // 命名指派
wallet = '{default:0}; // 全欄位設為 0
wallet = s_money'{int:1, dollars:2}; // 指定型別預設值
// 宣告匿名結構並初始化
struct {
int A, B, C;
} ABC = '{3{1}}; // A = B = C = 1
// 結構陣列初始化
s_money purse [1:0] = '{'{2, 4.25}, '{7, 1.5}};
```
## Fixed Arrays
* 固定大小陣列(Fixed Array) 是用來儲存連續記憶體位置中的多個值。
* 宣告方式:
* int myFIFO[0:7]; 或 int urFIFO[8]; → 都會建立 8 個整數元素
* 支援 多維陣列(Multidimensional Arrays):
* 宣告方式:int myArray[2][3]; → 2 列 3 行
* 使用 foreach 迴圈 可方便地走訪每個陣列元素
```
module tb;
int myFIFO [0:7]; // 一維陣列,共 8 個元素
int myArray [2][3]; // 二維陣列:2 列 3 欄
initial begin
myFIFO[5] = 32'hface_cafe;
myArray[1][1] = 7;
// 走訪一維陣列
foreach (myFIFO[i])
$display("myFIFO[%0d] = 0x%0h", i, myFIFO[i]);
// 走訪二維陣列
foreach (myArray[i])
foreach (myArray[i][j])
$display("myArray[%0d][%0d] = %0d", i, j, myArray[i][j]);
end
endmodule
```
## Void
* void 資料型別代表「沒有回傳值」。
* 常用在以下情境:
* function 的回傳型別 → 表示不會回傳任何值
* task 也可加上 void(雖然不是必要),但可增加語意清楚性
* 加上 void 是在提醒模擬器與開發者:
👉 「這段程式會執行某些操作,但不會回傳結果。」
```
function void display ();
$display("我不會回傳任何值");
endfunction
task void display ();
#10 $display("我也不會回傳值");
endtask
```