![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CZiV2MhJjYygDMlJzN2YmM0YmZjJjY5kTM3QjNiFzY18CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
兩态資料類型mp.weixin.qq.com
自定義、枚舉、結構體類型mp.weixin.qq.com
1.兩态資料類型
Verilog有兩種基本資料類型:變量(reg)和網線(wire),這是四态的資料類型(0、1、X、Z)。
RTL代碼使用變量(reg)存儲組合邏輯和時序邏輯的數值,可以是- 标量
- 向量(reg[7:0] bus_addr)、
- 有符号數32位變量(integer)、
- 無符号數64位的變量(time)、
- 浮點數(real)
- 變量也可以用來定義一個固定大小的數組
即這些變量的存儲是靜态的,意味着所有的變量在整個仿真過程中不能使用堆棧來儲存參數和目前值。
網線用來連接配接兩個設計子產品,如門級元件或例化子產品。
兩态(1/0)資料類型:SystemVerilog中的兩态資料類型減少了仿真器對記憶體的使用和提高仿真的運作效率。
其中,bit是無符号數,shortint、int、longint、byte是有符号數。
基本資料類型
整數資料類型
兩态和有符号資料類型
例子:
bit a;//兩态,單比特
bit[31:0] b32; //兩态,32比特無符号數
Int c32; //兩,32比特有符号數
byte d8; //兩态,8比特有符号數
shortint e16;//兩态,16比特有符号數
longint 1;//兩态 ,64比特有符号數
在資料算術運算操作的過程中,需要時刻注意區分有符号(shortint、int、longint、byte、integer)和無符号資料類型。上述這些都是整型資料類型。
SystemVerilog對reg的資料類型做了改進,reg可以被連續指派語句、門邏輯和子產品直接驅動。
SystemVerilog引入一個新的四态資料類型logic,可以替代reg;但不能用在雙向總線和多驅動的情況下,此時隻能使用網線類型(wire)。
2.自定義類型
通過使用者自定義類型,簡化了verilog代碼量并實作更多功能;
使用者自定義類型使得代碼的可讀性更強;
通過typedef來建立使用者自定義類型;
通過enmu來建立枚舉類型;
通過struct來建立結構體類型;
SV提供自定義類型可以幫助使用者建構更高抽象層的資料類型;
同C語言一樣,使用者可以利用已有的資料類型定義新的資料類型,一旦定義了新的資料類型,就可以利用該類型聲明變量。
Typedef int unsigned unit;//定義新類型unit
unit a,b;//unit自定義類型unit聲明的2個變量
注意:為了代碼可讀性,通常添加“_t”字尾表示它是一個自定義類型(type),而不是比變量。
在某些時候,自定義一個新的資料類型也是必須的,因為在SystemVerilog中要通過資料類型的辨別符才可以做類型轉換,如代碼所示。
使用者自定義類型執行個體module test_ typedef( );
typedef enum (red, green, blue, yellow, white, black) colors ;
colors my colors;
initial
begin
$display(“my_ color’s default vaule is %s”,my_colors );
my_colors = green;
//my_ colors=l; //錯誤使用方法,需要做資料類型轉換
my_ co1ors=colors’(2); 通過colors資料類型辨別符做類型轉換
$disp1ay( “my_co1or is % s” ,my_colors.name);
end
endmodul e
3.枚舉類型
枚舉類型(enum)可以描述變量的合法值範圍,其每一個值都需要提供一個使用者自定義的名字;
枚舉類型 IC可以擁有Icer1,Icer2,Icer3.....IcerN數值,
即enmu{Icer1,Icer2,Icer3.....IcerN} IC;
Verilog語言不支援枚舉類型,是以為了提供類似于枚舉類型設計方式,我們不得不采用
參數來表示可取值的範圍,或者使用
宏來定義各個合法值的宏名稱。
使用宏定義和參數
使用枚舉類型
預設的枚舉類型是int,即32位的二值邏輯資料類型;
為了更準确的描述變量,SV允許指明其資料類型,例如:
enum bit {TRUE,FALSE} Boolean;
enum logic [1:0] {WAITE,LOAD,READY} state;
自定義枚舉類型如果枚舉類型變量被指派,那麼所賦的值應在其數值範圍。
Enum logic {2:0} {WAITE=3’b001,LOAD=3’b010,READY=3’b100} state;
如果枚舉變量是四值邏輯,那麼将其值賦為X或者Z也是合法;
enum logic {ON=1’b1,OFF=1’b z} out;
如果枚舉類型并沒有伴随着typedef,那麼該枚舉類型指的是
匿名枚舉類型;此時變量名應伴随其後; 将typedef與enum合并,可以将匿名枚舉類型聲明為自定義類型,這就使得可以用同一個枚舉類型來聲明多個變量或者線網; typedef enum {WAITE,LOAD,READY} states_t; States_t state,next_state; verilog或者SV可以在不同的資料類型之間通過隐性轉換,進行直接指派,是以verilog/SV的資料類型轉換是寬松的; 枚舉類型指派枚舉類型指派時則相對嚴格,例如下面的例子中,指派操作符“-”的左右兩側應該盡量為相同的枚舉類型。
Typedef enum {WAITE, LOAD, READY} states_t;
states_t state, next_State ;
int foo;
state = next_state; //合法操作
foo=state+1;//合法操作
state=foo+1;//非法指派
state = states_t’ (foo + 1) ;//合法指派
state = state + 1; //非法指派
state= states_t’ (state + 1) //合法指派
state++; // 非法指派
next_state += state; //非法指派
SystemVerilog為枚舉類型提供了如下内置方法( method)來友善操作 function enum first ():傳回枚舉類型中第一個成員的值。
Function enum last ():傳回枚舉類型中最後一個成員的值。
Function enum next ( int unsigned N=1):以目前成員為起點,傳回後續第N個成員的值,預設是下一個成員的值;若起點為最後一個成員,則預設傳回第一個成員的值。
Function enum prev ( int unsigned N=1):以目前成員為起點,傳回前面第N個成員的值,預設是前面一個成員;若起點為第一個成員,則預設傳回最後一個成員的值。
Function int num ():傳回該枚舉類型的成員數目。
Function string name ():以字元串的形式傳回該成員名字。
4.結構體類型
SV添加了和C一樣的結構體struct,而結構體成員可以是任何變量類型,包括自定義類型或者其他常量類型;
Struct{
Int a,b;//32位變量
Opcode_t opcode;//使用者自定義類型
logic [23:0] address;//24位變量
Bit error;//1位變量
}Instruction_Word;//變量名
結構體類型的變量可以用來索引到其内部的變量,索引方式同C一樣。
<structure_name>.<variable_name>
Instruction_Word.address=32’hF000001E;
結構體類型預設也是變量類型,使用者可以顯式聲明為var或者wire類型;
類似與于枚舉類型,結構體類型也可以伴随着typedef來實作自定義結構體類型;
Typedef struct { //自定義結構體
logic [31:0] a,b;
Logic [7:0] opcode;
Logic [23:0] address;
}instruction_word_t IW;// 結構體變量聲明
結構體變量可以通過索引其各個成員做依次的成員指派:
Always @(posedge clk or negedge rst_n)begin
If(!rst_n)begin
IW.a=100;//結構體成員
IW.b=5;
IW.address=0;
End
else begin
......
end
end
也可以通過分号’ 和花括号{}來實作整體賦初值;
IW=’ {100,3,8’hFF,0};
IW=’ {addres:0,opcode:8’hFF,a:100,b:5}; //成員和數值通過冒号:一一對應。
5.字元串類型
SV中引入string類型來容納可變長度的字元串;
字元串類型變量的存儲單元為byte類型;
字元串類型變量長度為N,則字元成員索引值從0到N-1;
不同與C語言,字元串結尾沒有空字元 “0”;
字元串的記憶體是動态配置設定的,使用者無需擔心記憶體空間管理;
字元串内建方法:
str..len():傳回字元串長度
str.putc(I,c):将第i個字元替換為字元c,等同于str[i]=c;
str.getc(i): 傳回第i個字元;
str.substr(i,j): 傳回第i個字元到第j個字元的字元串
str.tolower():傳回一個小寫字元串;
str.toupper(): 傳回一個大寫字元串;
str.{atoi(),atohex(),atooct(),atobin()}:傳回十進制、十六進制、八進制、二進制資料;