SystemVerilog For Design
声明空间
在verilog中,reg 、wire、task、function
等的定义都必须在module之内,这些声明都是局部的,因此只能在模块内部使用,无法跨模块使用。如果希望在多个模块中使用某个function
,则需要在每一个模块内都重新定义。特别是使用user-defined type,需要在每一个模块内都重复进行typedef
,非常的冗余,且容易出错。
为此system verilog拓展了声明空间。
package
package的定义
package是一个独立的声明空间,因此不能嵌入在module内部。
package是通过两个关键字进行定义的——package
与endpackage
。可综合的package可以包含如下的内容:
parameter
和localparam
定义的常数(在package中,两个是一样的,都不能在外部被修改)。const
定义的变量。typedef
定义的自定义类型。- automatic
task
和automaticfunction
。 import
导入其他package。- 操作符重载。
package还可以包含全局变量声明、静态任务定义和静态函数定义。然而,这些都是不可综合的。
一个package的实例如下:
1 | package definitions; |
package的引用
package可以在module和interface中,通过如下四种方式进行引用。
- 直接使用名称空间决议运算符(
::
) - 将package中特定的item通过
import
导入到module和interface中 - 使用通配符
*
将package中的item通过import
导入到module和interface中 - 将package中的内容
import
到$unit
声明空间
名称空间决议运算符
1 | module ALU ( |
import特定item
1 | module ALU ( |
Note
Importing an enumerated type definition does not import the labels used within that definition.
使用通配符导入
1 | module ALU ( |
导入到$unit
1 | // import specific package items into $unit |
或者使用下面的通配符导入:
1 | // import specific package items into $unit |
导入到$unit注意事项
文件导入顺序
如果在A
文件中使用import
导入声明到$unit
中,而B
文件不使用import
语句来导入。这时候,只有B
文件在A
之后导入,B
中才能使用导入的声明,如果在A
之间被导入,则为报错(或者使用隐式声明)。
每个文件都import
虽然每个文件都是用import
导入声明到$unit
,可以解决上述的问题。但是,这几个文件同时编译时,会导致重复定义的错误。
解决办法
与c当中的头文件类似,使用宏来防止被重复导入。
一个可行的示例如下:
创建一个名为definitions.pkg的文件,其内容如下:
1 | // if the already-compiled flag is not set... |
然后将下面的语句放在每一个需要导入该package的文件开头
1 | ‘include "definitions.pkg" |
$unit compilation-unit
SystemVerilog语言在Verilog中增加了一个称为compilation-unit(编译单元)的概念——一个编译单元是同时编译的所有源文件。compilation-unit为软件工具提供了一种对整体设计的子块进行单独编译的手段。一个子块可能包含单个模块,也可能包含多个模块。模块可能包含在单个文件中,也可能包含在多个文件中。
SystemVerilog语言扩展了Verilog的声明空间,允许声明在package
、module
、interface
和program block
边界之外进行。这些外部声明处于一个compilation-unit范围内,对于同时编译的所有模块都是可见的。
compilation-unit示例
1 | /******************* External declarations *******************/ |
Note
External compilation-unit scope declarations are not global
Tip
A declaration in the compilation-unit scope is not the same as a global declaration. A true global declaration, such as a global variable or function, would be shared by all modules that make up a design, regardless of whether or not source files are compiled separately or at the same time.