结构体用于将多个变量组合在一个通用名称下。设计通常具有逻辑信号组,例如总线协议的控制信号,或状态控制器内使用的信号。结构体提供了将这些相关变量捆绑在一起的方法。结构体中的所有变量都可以单个赋值,或者每个变量都可以单独赋值。结构体包可以复制到具有相同定义的另一个结构体,并通过模块端口、任务或函数进出。
结构体是使用struct关键字声明的,类似于C语言。struct关键字后面跟着一个开始的大括号( { )变量声明列表,结束的大括号(}),然后是结构体的名称。
一个结构体可以将任意数量的变量数据类型捆绑在一起,用户自定义类型、Parameter和localparam常量也可以包含在一个结构体中,结构体中的Parameter不能像模块中的Parameter那样重新定义,结构体中的参数被视为localparam。
结构体中的变量称为结构体成员。每个成员都有一个名称,可用于从结构体中选择该成员。使用结构体的名称引用结构体成员,后跟句点(.)然后是成员的名字。这与C中的语法相同。例如,要为前面结构体的address成员赋值,引用为:
结构体不同于数组,因为数组是所有类型和大小相同的元素的集合,而结构体是不同类型和大小的变量和常量的集合。另一个区别是,数组的元素是通过在数组中使用索引来引用的;结构体的成员是通过使用成员名称来引用的。
可以为整个结构体指定一个结构体表达式。结构体表达式是使用逗号分隔的值列表形成的,这些值包含在标记’{}之间,这与将一组值分配给数组的方式相同,大括号必须包含结构体中每个成员的值。例如:
结构体表达式中的值必须按照在结构体中定义的顺序列出,如前一示例所示。或者,结构体表达式可以指定要为其赋值的结构体成员的名称,其中成员名称和值用冒号(:)分隔。结构体表达式中的成员名称称为tags。指定成员名称后,表达式列表可以是任意顺序。
在同一个结构体表达式中混合按名称和按顺序赋值是非法的。
结构体表达式中的默认值。结构体表达式可以通过指定默认值为一个结构体的多个成员指定值,默认值是使用default关键字指定的。
结构体表达式还可以包含对特定结构体成员的混合赋值,以及对所有其他成员指定默认值。
结构体中的枚举数据类型。前两个带有默认值的示例存在语义错误,分配给结构体成员的默认值必须与成员的数据类型兼容。由于大多数SystemVerilog变量都是弱类型的,因此几乎所有默认值都是兼容的。然而,枚举数据类型变量的类型更强。对枚举数据类型变量的赋值必须是其枚举列表中的标签,或者是同一枚举数据类型定义的另一个枚举变量。
上述instruction_word 的两个赋值语句试图将opcode的默认值赋值为0。这是opcode的非法值,它是一个opcode_t枚举数据类型变量(opcode_t的typedef定义是之前枚举变量章节)。当结构体的成员是枚举数据类型变量时,结构体表达式必须为该成员指定合法的显式值。可以为所有其他成员指定默认值。例如:
用户自定义类型可以使用typedef关键字从结构体中创建。将结构体声明为用户自定义类型不会分配任何存储空间。在使用该结构体之前,必须声明该用户自定义类型的网络或变量。
不使用typedef的结构体被定义为匿名结构体。使用typedef声明的结构体被视为自定义结构体。匿名结构体和自定义结构体都可以在模块中定义,但这些本地(局部)定义只能在该模块中使用。自定义结构体也可以在包中定义,并导入到需要结构体定义的设计块中。包中定义的自定义结构体可用于多个模块和验证测试台。
一个自定义结构体可以复制到另一个自定义结构体,只要这两个结构体是从同一个自定义结构体定义声明的。以下示例使用了上节中所示的结构体定义和声明。
匿名结构体不能作为一个整体复制,但可以一次复制一个成员:
全部0条评论
快来发表一下你的评论吧 !