# 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 ```