作為引子,首先來看一段描述,該段介紹了SystemVerilog
對比Verilog
在RTL
設計和建模時的新特性之一(logic
數據類型),然后下文我再展開對比介紹Verilog
和SystemVerilog
中的基本數據類型。(該段內容引用自 @Dr. Pong P. Chu 的書籍列表之《FPGA Prototyping by SystemVerilog Examples: Xilinx MicroBlaze MCS SoC》的書籍說明部分)
《SystemVerilog vs Verilog in RTL Design》By Pong P. Chu, Chapter 3.1 logic DATA TYPE
Verilog‐2001 divides the data types into a "net" group and a "variable" group. The former is used in the output of a continuous assignment and the
wire
type is the most commonly used type in the group. The latter is used in the output of a procedural assignment and thereg
type is the most commonly used type in the group. Verilog‐2001 has a specific set of rules and restrictions regarding the assignment and connection of signals from the different groups.The names of the
wire
andreg
types are misleading. A signal declared with thewire
type can be a connection wire or a component with memory (e.g., a latch). A variable declared with thereg
type may or may not infer a register. It can be a connecting wire, a register, a latch, or a "C‐like software variable". Furthermore, the rules and restrictions imposed on assignment and connection of signals from different the groups are confusing and unnecessary.SystemVerilog introduces the
logic
data type. It can be used in the variable group or net group, which is inferred automatically from context. Thelogic
type can replace thewire
andreg
types in most codes. In addition, its name does not imply a specific hardware component and thus is more descriptive.
1. Verilog
的數據類型
Verilog
語言提供兩組基本的數據類型:變量數據類型(variable
)和線網數據類型(net
),這兩種類型都是四值邏輯。具體請參考《IEEE Standard for Verilog》Chapter 4 Data types。
- 對線網的聲明進行簡化,即:
net_type list_of_net_identifiers
,其中net_type
包含我們常用的如wire
、tri
、wand
、wor
等等(參考完整的線網聲明:net_declaration); - 對變量的聲明進行簡化,即:
reg | integer | time | real | realtime
+list_of_variable_identifiers
(參考完整的變量聲明:variable_declaration)。
可以看到,在Verilog
中,線網及變量的聲明都很簡單,都只有兩部分:如net_type | reg | integer
+ 聲明列表
即可。另外,再來看Verilog
中的賦值,Verilog
中將連續賦值(Continuous assignment
)及過程賦值(Procedural assignment
)中的左值(LHS
)分別限制為了線網(net
)和變量(variable
)類型,換言之,如我們常用的wire
類型(net
)只可以被連續賦值,以及我們常用的reg
類型(variable
)只可以被過程賦值:
在Verilog
中,reg
經常用來表示存儲組合邏輯或時序邏輯的變量,不過很多初學者會混淆其綜合后的硬件單元。實際上,reg
變量並不一定會被綜合為寄存器(register
),之所以定義成reg
類型,是表示從仿真的語義上來講需要一個存儲單元,而與綜合后的硬件電路沒有直接的關聯,所以對初學者而言有時會具有誤導性。而在SystemVerilog
中,我們便引入了更具有描述性的logic
數據類型,下面來介紹SystemVerilog
中的數據類型。
2. SystemVerilog
的數據類型
SystemVerilog
添加了很多新的數據類型,但依然可以分為兩組類型:變量類型(variable
)和線網類型(net
),來看他們的聲明及定義如下,具體請參考《IEEE Standard for SystemVerilog》Chapter 6 Data types。
- 對線網類型的聲明進行簡化,即(參考完整的線網聲明:net_declaration):
net_type data_type list_of_net_decl_assignments;
- 對變量類型的聲明進行簡化,即(參考完整的變量聲明:variable_declaration):
[const][var] data_type list_of_variable_decl_assignments;
對比上述簡化版之后,就可以發現:SystemVerilog
區分為類型和數據類型,且兩種類型(net
和variable
)的變量聲明方式相同,都是:類型
+ 數據類型
+ 聲明列表
。其中線網類型(net_type
)包含supply0 | supply1 | tri | triand | trior | trireg | tri0 | tri1 | uwire | wire | wand | wor
,與Verilog
相同;而變量類型(variable_type
)只需要關鍵字var
即可,並且var
可以省略。而Verilog
中的reg
、integer
、time
、real
、realtime
在SystemVerilog
中則都是指數據類型,並且SystemVerilog
添加了很多新的數據類型:
其中又可以分為二值邏輯、四值邏輯;新增了枚舉(enum
)、結構體(struct
)、字符串(string
)、類(class
)等一些新的數據類型,這里不展開介紹。只要明白,僅有數據類型時(如reg r;
、byte b;
、logic c;
),其默認表示的是變量類型,因為關鍵字var
可以省略。另外,數據類型也可以省略,僅有類型聲明時(如wire w;
、var v;
),此時數據類型被隱式聲明為logic
:
- If a data type is not specified in the net declaration or if only a range and/or signing is specified, then the data type of the net is implicitly declared as
logic
. - If a data type is not specified in the variable declaration or if only a range and/or signing is specified, then the data type of the variable is implicitly declared as
logic
.
reg r ; // equivalent to "var reg r;"
logic [15:0] l ; // equivalent to "var logic [15:0] l;"
var byte my_byte; // equivalent to "byte my_byte;"
wire w ; // equivalent to "wire logic w;"
wire [15:0] ww ; // equivalent to "wire logic [15:0] ww;"
var v ; // equivalent to "var logic v;"
var [15:0] vw ; // equivalent to "var logic [15:0] vw;"
再來看到,像reg
、bit
、byte
、int
等,在SystemVerilog
中,都屬於數據類型(data_type
),那么既然線網類型的聲明也是net_type
+ data_type
,則有如tri reg t;
、inout wire reg p;
、wire int i;
等等,又是否合法呢?顯然是不合法的。在《IEEE Standard for SystemVerilog》Chapter 6.7.1 Net declarations with built-in net types 中對線網類型(net_type
)的數據類型(data_type
)做了限制(Certain restrictions apply to the data type of a net):
- A valid data type for a net shall be one of the following:
- A 4-state integral type, including a packed array or packed structure.
- A fixed-size unpacked array or unpacked structure, where each element has a valid data type for a net.
- A lexical restriction applies to the use of the reg keyword in a net or port declaration. A net type keyword shall not be followed directly by the reg keyword. The reg keyword can be used in a net or port declaration if there are lexical elements between the net type keyword and the reg keyword.
這說明了線網類型(net_type
)的數據類型(data_type
)只能為四值數據類型(4-state data type),並且net_type reg list_of_net_decl;
是非法的。以下都是合法的線網類型聲明(net declarations
):
wire logic w;
wire [15:0] ww;
trireg (large) logic #(0,0,0) cap1;
typedef logic [31:0] addressT;
wire addressT w1;
wire struct packed { logic ecc; logic [7:0] data; } memsig;
最后再來看賦值,主要注意其連續賦值(Continuous assignment
)中的左值(LHS
)與Verilog
的區別:在SystemVerilog
中,連續賦值的左值支持變量類型,而Verilog
僅僅支持線網類型。
所以,如logic [15:0] data;
,雖然默認表示的是變量類型(等價於var logic [15:0] data;
),但是也支持連續賦值。由於其既支持連續賦值,又支持過程賦值,同時又是四值邏輯,所以logic
數據類型可以代替Verilog
設計代碼中的大多數wire
類型和reg
類型,至於被綜合成什么硬件,依然要由綜合器根據上下文來進行推斷。