---
# System prepended metadata

title: '[DV筆記] Systemverilog - 數據結構'
tags: [DV筆記, systemverilog]

---

# [[DV筆記] Systemverilog - 數據結構](/8N4Qts9VTAOzq-7Bqp_3HA)

## **基本數據類型**
|   Type   | Width | State |  Signed  |
|:--------:|:-----:|:-----:|:--------:|
|   reg    |   1   |   4   | unsigned |
|   wire   |   1   |   4   | unsigned |
|  logic   |   1   |   4   | unsigned |
|   bit    |   1   |   2   |  signed  |
|   byte   |   8   |   2   |  signed  |
| shortint |  16   |   2   |  signed  |
|   int    |  32   |   2   |  signed  |
| longint  |  64   |   2   |  signed  |
|   time   |  64   |   4   | unsigned |

Verilog 中基本的數據類型為 reg 和 wire，為 4 state的數據類型，可以為 0, 1, x, z
Systemverilog 新增 logic 數據類型，可已在驗證環境中為 reg 或是 wire，同樣也是 4 state的數據類型
使用 2 state 的數據類型可以減少 Memory 的使用

**補充一下**
wire 只能在使用在 blocking
reg 則需要在 initial 或是 alwauys block 中
基本上如果是在testbench中，可以無腦使用 logic 

## **Array 陣列類型**
### Static Array
顧名思義就是一開始就固定長度的 array，又區分為 packed 和 Unpacked
寫在name前面表示為 packed -> Memory 一定會分配連續空間
寫在name後面表示為 unpacked -> Memory 不一定會分配連續空間

```static array=
bit [3:0][4:0] static_array [1:0][2:0];
```
理解方向為由左至右， unpacked dimention 先，再讀 packed dimention，所以這是一個 [1:0][2:0][3:0][4:0] 的4維array

> [這邊讀的順序一開始讀的時候真的是完全搞不懂，後來看到有文章說是逆時鐘看法比較好記憶，不過工作一陣子後還是容易忘]

針對 packed dimention 賦值:
```
bit [2:0] packed_array; //packed array "不能" 寫成 [3] packed_array
packed_array = 3'b0;
```

針對 unpacked dimention 賦值:
```
bit unpacked_array[0:2]; //也可以寫成 bit unpacked_array[3]
unpacked_array = '{3{0}};
// 可以設定 default 值的寫法:
unpacked_array = '{default:0};
```

### Dynamic Array
可以在compile之後才設定Array size，以節省 Memory 空間
```
int dynamic_array[];
//在initial block 裡才設定大小
initial begin
dynamic_array = new[5]; //用 new 去設定大小
dynamic_array.delete(); //清空整個 Array
end
```

### Queues
類似 C++ 的 deque，可以隨時插入元素，非常方便使用

> [在工作的時候也是很喜歡使用!]

```
int queues[$]; //就是使用這個 $ 符號即可
queues = {0,1,2};
//好用的 function:
queues.insert(1,3); //在 index==1 插入0 queues = {0,3,1,2}
queues.delete(2); //注意是delete index == 2, queues = {0,3,2}
queues.pop_front(); //queues = {3,2}
queues.pop_back();  //queues = {3}
queues = {queues,1,2}; //queues = {3,1,2}
queues = queues[1:$]; //queues = {1,2}, $表示到queue 的最後一個元素
queues.delete(); //清空 queue, 也可以寫 queues = {};
```

queue 非常方便使用，所以也特別整理可以直接使用的 function!
```
int q [$];
q = {0,1,1,2,3,3,4,5};
q.min(); //return 0
q.max(); //return 5
q.unique() // return 0,1,2,3,4,5 有點像是變成 C++ 的 set

//查找系列
q.find_index with (item>3); //return queue裡面 >3 的整數的 index ,也就是 6,7, 這裡的 item 是一個隱含變量，代表隊列中的當前元素。它不需要顯式地定義類型，因為它會自動匹配隊列中元素的類型。
q.find_first_index with (item==3); //return 4
q.find_last_index with (item==3); //return 5

//排序系列! 實用
q.reverse(); //q 變成 {5,4,3,3,2,1,1,0}, 不會 return
q.sort(); // 從 小到大 排序
q.rsort(); //從 大到小 排序
q.shuffle(); //亂序
```

### Associate Arrays
就是Hash，資料不連續或是需要快速查找可以使用這個!
```
int assoc [string]; // 表示 index 為 string, 存放 int 類型的數據
int var;

assoc.exists("does_it_exit"); //查找 key 是否存在
assoc.delete("delete"); //delete key
assoc.delete(); //清空accociate array
assoc.num(); //return key 數目
assoc.first(var); // return var = 第一個 key
assoc.last(var); //return var = 最後一個 key
assoc.next(var); //return var= 下一個 key
assoc.prev(var); //return var= 上一個 key

//整理的時候還意外查到一個用法:
int assoc[*]; //可以用*來表示索引可以是任何整數類型，包括 int、shortint、longint、byte 等，甚至可以是更複雜的整數表達式。 -->很方便!
```

## String
string 雖然在 verification 通常只是用來print debug message，並沒有到那麼重要，不過如果面試會考一些對 string 的操作了話，還是需要知道一些基本的 fucntion:

```
string s;
s= "abc";
s.getc(0); //return 'a'
s.toupper(); //s變成 "ABC"
s.tolower(); //s變成 "abc"
s.putc(2,"!"); //s 變成 "ab!"
s={s,"123"}; //s = "ab!123"
s.substr(2,5); // return "!123"
```

## 組合數據
### Struct
可以把多種數據結構組合成一個數據結構，雖然後來比較常用 class

```
struct st {
    int id;
    bit gender;
    string name;
} person;

person.id = 5;
person.gender = 1;
person.name = "TOM";
```

通常 struct 會跟 typedef 搭配使用，這樣就可以用一個 struct 定義，去建構不同的數據結構!

```
typedef struct{
    int id;
    bit gender;
    string name;
} person;

person TOM = '{0,1,"TOM"}; //可以這樣初始化
person MAY = '{1,0,"MAY"};
```


### Union
講到 struct 就要搭配 union 這個數據結構一起整理

union 用於將多個變量組合在同一個存儲空間中。這意味著在任意時間內，只有一個成員是有效的。union 提供了一種節省存儲空間的方法，特別適用於需要在不同時間存取不同類型數據的情況。
聲明和使用：聲明聯合體變量 data 並設置其成員值。注意，由於所有成員共享同一存儲空間，設置一個成員的值會影響其他成員

```
typedef union {
        int int_val;
        byte byte_val[4];
    } data_t;
//也就是 int_val 跟 byte_val在記憶體中是相同的區域，只是名字不一樣
data_t union_data;
union_data.int_val = 32'habcdefgh;
//這邊 byte_val[4] 也同時被set 為 '{8'hgh,8'hef,8'hcd,8'hab}，要注意 byte[0] = 8'hgh

```
### Enum
enum 是在描述 state machine 十分常用的數據結構，可以將 參數的值改以容易識別的名稱表示

```
typedef enum {red,green,blue} pixel_t;
pixel_t pixel;
pixel = red; //default 會照 red = 0, green = 1, blue = 2 這樣表示
```



## 結語
數據結構整理差不多到這邊啦，可能不盡詳細，不過基本上已經夠用啦!重新再整理一遍還是會回想一些已經忘記的語法，這也是想再把筆記整理好的原因




