0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

SystemVerilog包的简介与使用

OpenFPGA 来源:OpenFPGA 作者:碎碎思 2022-06-15 09:18 次阅读

数字硬件建模SystemVerilog(十一)-SystemVerilog 包

最初的Verilog语言没有一个可用于多个模块的定义。每个模块都必须有任务、函数、常量和其他共享定义的冗余副本。传统的Verilog编码风格是将共享定义放在一个单独的文件中,然后可以使用“include”编译指令将其包含在其他文件中。该指令指示编译器复制包含文件的内容,并将这些内容粘贴到“include”指令的位置。虽然使用文件包含有助于减少代码冗余,但对于代码重用和维护来说,它是一种笨拙的编码方式。

SystemVerilog将包(packages)添加到最初的Verilog HDL中。包是可以保存共享定义的声明空间。多个模块和接口可以直接引用这些共享定义,或者通过定义导入特定的包项,或者通过导入整个包来引用这些共享定义。包解决了必须在多个模块中复制定义的问题,以及使用xxx将定义复制到多个模块中的尴尬。

包声明

SystemVerilog包是在关键字package和endpackage之间定义的。包是一个独立的声明空间。包的概念继承于VHDL。它不嵌入Verilog模块中。包中的定义和声明称为包项。包可以包含的可综合定义包括:

  • parameter,localparam和const常量声明
  • typedef用户自定义类型
  • task 和 function定义
  • 从其他包import声明
  • 包链接的export声明
  • 时间单位定义

包还可以包含不可综合的验证定义,例如:类(classe)。本文没有介绍验证结构体。

示例4-1:包含多个包项的包定义
`begin_keywords"1800-2012"//useSystemVerilog-2012keywords
packagedefinitions_pkg;
timeunit1ns/1ns;

parameterVERSION="1.1";

`ifdef_64bit
typedeflogic[63:0]word_t;
`elsif_32bit
typedeflogic[31:0]word_t;
`else//defaultis16bit
typedeflogic[15:0]word_t;
`endif

typedefenumlogic[1:0]{ADD,SUB,MULT}opcodes_t;

typedefstruct{
word_ta,b;
opcodes_topcode_e;
}instruction_t;

functionautomaticword_tmultiplier(inputword_ta,b);
//codeforacustomn-bitmultiplier
endfunction
endpackage:definitions_pkg
`end_keywords

本文后面将讨论示例4-1中所示的枚举enum和结构体struct构造。示例中的word_t用户自定义类型定义位于’ifdef条件编译指令中,该指令将word_t定义为16位向量、32位向量或64位向量。“ifdef构造允许工程师选择调用编译器时要编译的代码。所有使用word_t用户自定义类型的设计模块将使用编译包时选择的word大小。

最佳实践指南4-1
对包常量仅使用localparam或const定义。不要在包中使用parameter定义

包中定义的parameter与模块中定义的parameter不同。可以为模块的每个实例重新定义模块级parameter常量。无法对包中parameter重新定义,因为它不是模块实例的一部分。在包中,parameter与localparam相同。

使用包项

包中的定义和声明称为包项。模块和接口可以通过四种方式引用包项:

  • 通配符导入所有包项
  • 显式地导入特定包项
  • 明确导入特定包和包项
  • 将包项导入$unit声明空间

本节将讨论引用包项目的前三种方法。后面章节将讨论导入$unit声明空间中。

包项目的通配符导入(wildcard import)

模块引用包项的最简单也是最常见的方法是使用通配符导入语句从包中导入所有项。例如:

cb7ab8b0-ec43-11ec-ba43-dac502259ad0.png

包名称后面的(::)双冒号是作用域解析运算符。它指示编译器在另一个位置(范围)查找信息——本例中是definitions_pkg包。

星号(*)是通配符标记。通配符有效地将导入的包添加到SystemVeriog使用的搜索路径中。

当SystemVerilog编译器遇到标识符(名称)时,它将首先在本地范围内搜索该标识符的定义。本地范围内可以是任务、函数、begin-end块、模块、接口或包。如果在本地范围中找不到标识符定义;接下来,编译器将搜索下一个作用域级别,直到到达模块、接口或包边界。如果未找到标识符定义,则搜索任何通配符导入的包;最后,工具将在$unit声明空间中搜索。通配符导入搜索规则的完整语义规则比这个描述更复杂,并在IEEE 1800 SystemVerilog标准中定义。

示例4-2演示了如何使用通配符导入语句。

示例4-2:使用包通配符导入
`begin_keywords"1800-2012"//useSystemVerilog-2012keywords
modulealu
(inputdefinitions_pkg::instruction_tiw,
inputlogicclk,
outputdefinitions_pkg::word_tresult
);
always_ff@(posedgeclk)begin
case(iw.opcode)
definitions_pkg::ADD:result=iw.a+iw.b;
definitions_pkg::SUB:result=iw.a-iw.b;
definitions_pkg:result=definitions_pkg::
multiplier(iw.a,iw.b);
endcase
end
endmodule:alu
`end_keywords

在本例中,通配符导入的作用是将definitions_pkg包添加到模块的标识符搜索路径。端口列表可以引用instruction_t用户自定义类型,编译器将在包中找到该定义。同样,case语句可以引用opcode使用的枚举数据类型标签,这些标签的定义也将在包中找到。

但是, 当包中的一项或多项需要在模块中多次引用时,每次显式地引用包的名称则太过麻烦了, 我们希望将包中包项导入到设计块中(使用通配符全部导入)。

显式地导入特定包项

SystemVerilog还允许将特定的包项导入模块,而无需将整个包添加到该模块的标识符搜索路径中。

显式地导入特定包项的一般语法为:

importpackage_name::item_name;

例4-3,使用显式地导入将特定的包项带入模块。显式导入比使用通配符导入更简单,也使模块更具自文档性,很容易看出从包中使用了哪些包项。

示例4-3:将特定的包项导入模块
`begin_keywords"1800-2012"//useSystemVerilog-2012keywords
modulealu
importdefinitions_pkg::instruction_t,
definitions_pkg::word_t;
(inputinstruction_tiw,
inputlogicclk,
outputword_tresult
);
importdefinitions_pkg::ADD;
importdefinitions_pkg::SUB;
importdefinitions_pkg::MULT;
importdefinitions_pkg::multiplier;

always_combbegin
case(iw.opcode)
ADD:result=iw.a+iw.b;
SUB:result=iw.a-iw.b;
MULT:result=multiplier(iw.a,iw.b);
endcase
end
endmodule:alu
`end_keywords
笔记
枚举数据类型定义的显式导入不会导入该定义中使用的标签,所以对于枚举数据类型定义的标签也必须显式导入。后面会详细介绍

声明包导入的位置

声明包导入的位置语句,无论是通配符导入还是特定包项导入:

  • 在模块端口列表之前——包项可以在端口定义和模块内使用。
  • 在模块端口列表之后-包项可以在模块内使用,但不能在端口定义内使用。
  • 模块定义之外——将包项导入伪全局unit声明空间及其危害。
笔记
在SystemVerilog-2009标准中添加了模块端口列表之前声明包导入语句。在SystemVerilog-2005中,声明包导入语句只能出现在端口列表之后,或者出现在unit声明空间中。

使用作用域解析运算符直接导入包

作用域解析运算符(::)可用于通过指定包名称和包中的特定项直接引用包项。

示例4-4使用作用域解析运算符引用了前面示例4-1中所示的包中定义的几个包项:

示例4-4:使用作用域解析运算符的显式包引用
`begin_keywords"1800-2012"//useSystemVerilog-2012keywords
modulealu
importdefinitions_pkg::*;//wildcardimport
(inputinstruction_tiw,
inputlogicclk,
outputword_tresult
);

always_combbegin
case(iw.opcode)
ADD:result=iw.a+iw.b;
SUB:result=iw.a-iw.b;
MULT:result=multiplier(iw.a,iw.b);
endcase
end
endmodule:alu
`end_keywords

显式引用包项有助于记录设计源代码。在示例4-4中,包名的使用使得找到instruction_t,word_t ADD, SUB, MULT 和 multiplier定义的地方变得很明显。但是,对于包项的每次使用,显式引用包名称比较冗长。声明包导入语句的一种更常见的方法是导入整个包,如前文所述。只有当多个包中有同名的定义,并且需要指明要从哪个包导入包项时,才需要本节中显式引用包。

多个包导入

较大的设计项目通常会使用几个包。一个模块或接口可以根据需要从任意多个包中导入。

导入多个包时,注意避免名称冲突。使用通配符导入时尤其如此。在下面的代码片段中,包cpu_pkg和gpu_pkg都有一个名为instruction_t的标识符(包项)。

cb90409a-ec43-11ec-ba43-dac502259ad0.png

在这个代码片段中:两个包中都定义了一个instruetion_t标识符,并且两个包都是通配符(::)导入的,变量instruction被声明为instruction_t类型。当仿真器、综合编译器或其他软件工具搜索instruction_t的定义时,它会在两个通配符导入的包中找到一个定义,并且不知道使用哪个定义。多个定义将导致编译或细化(Elaboration:是将设计组件绑定在一起的过程。Elaboration包括创建实例化,计算参数值,解析分层名称和连接nets。通常在引用compilation 和 elaboration阶段时,它们不会被区分,但通常直接被称为compilation。换句话说,“编译时错误”可能指的是run-time阶段之前的任何时间的错误。)错误。

当存在多个定义时,源代码必须显式引用或显式导入要在该模型中使用的定义,例如:

cbb63386-ec43-11ec-ba43-dac502259ad0.png

显式包引用优先于本地定义或包的显式导入,后者优先于通配符导入。前面代码段中的显式导入解决了processor模块中使用instruction_t定义时的模糊性。

包链

一个包可以显式地从另一个包导入定义,也可以通配符导入另一个包。但是,导入的项目在该包外不会自动可见。考虑下面的例子:

cbd2fd72-ec43-11ec-ba43-dac502259ad0.png

为了让模块alu使用来自两个包的定义,两个包都需要导入到模块alu。SystemVerilog能够链接包,因此模块只需导入链中的最后一个包,即前面代码段中的alu_types_pkg。包链是通过包组合导入和导出语句来完成的。

cbf23714-ec43-11ec-ba43-dac502259ad0.png

export语句可以显式导出特定项,或使用通配符导出从另一个包导入所有项。请注意,使用通配符导出时,仅导出包中实际使用的定义。在前面的片段中;base_types_pkg中word32_t的定义未在alu_types_pkg中使用,因此未链接,并且在alu模块中不可用。下面的显式导出可以添加到上面的alu_types_pkg示例中,链接到word32_t,这样它就可以在alu模块中使用。

cc0710b2-ec43-11ec-ba43-dac502259ad0.png
笔记
在写这本文的时候,一些仿真器和综合编译器还不支持包链。包链的export声明是SystemVerilog-2009标准的一部分。SystemVerilog-2005标准没有定义进行包链的方法。

包的编译顺序

SystemVerilog要求在引用包定义之前对其进行编译。这意味着编译包和模块时存在文件顺序依赖关系——必须先编译包。这也意味着引用包项的模块不能独立编译。如果工具支持单独的文件编译,则包必须与模块一起编译,或者已经预编译。

确保在引用包或包项的任何文件之前编译包的一种方法是控制编译命令中列出文件的顺序。

文件编译顺序通常由Linux“make”文件控制。也可以使用Verilog命令文件(使用-f调用选项读取)和脚本或批处理文件。

确保在引用包或包项的任何文件之前编译包的另一种方法是使用’include 编译指令指示编译器读取包含包的文件,’include指令放在包含对包项引用的每个设计或测试台文件的开头。

cc1b315a-ec43-11ec-ba43-dac502259ad0.png

使用“include指令”时需要注意一点,SystemVerilog不允许在同一编译中多次包含同一个包。可以通过放置’ifdef(“if defined-定义”)或’ifndef(“if not defined-未定义”)来实现围绕包定义的条件编译指令,以便编译器跳过已编译的包。条件编译指令允许SystemVerilog源代码根据宏名是否已使用’define指令定义进行选择性编译。

下面的示例使用’ifndef条件编译指令围绕包。当包含包的文件被编译器读入时,“未定义”测试将为真,包将被编译。编译的代码行包含一个’define指令,该指令设置了使用的宏名称。如果在编译器的同一调用过程中再次读取此文件,“未定义”测试将为false,并且将跳过’ifndef和endif之间的代码。

cc2fb1ca-ec43-11ec-ba43-dac502259ad0.png

综合条件

为了能够进行综合,包中定义的任务和函数必须声明为自动的(automatic),并且不能包含静态变量。此规则的原因是,综合将在引用包任务或函数的每个模块或接口中复制任务或函数。如果任务或函数在仿真中有静态存储,那么该存储将由任务或函数的所有引用共享,这是一种与复制不同的行为。通过将任务或函数声明为自动的,每次调用它时都会分配新的存储,使其行为与任务或函数的唯一副本相同。这确保了对包任务或函数的预综合引用的仿真行为与后综合行为相同。

出于仿真的原因,综合不支持包中的变量声明。在仿真中,一个包变量由导入该变量的所有模块共享。一个模块可以写入变量,另一个模块将看到新值。这种不通过模块端口传递值的模块间通信是不可综合的。

原文标题:SystemVerilog(十一)-SystemVerilog 包

文章出处:【微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 模块
    +关注

    关注

    7

    文章

    2692

    浏览量

    47426
  • Verilog
    +关注

    关注

    28

    文章

    1351

    浏览量

    110067
  • 函数
    +关注

    关注

    3

    文章

    4326

    浏览量

    62558

原文标题:SystemVerilog(十一)-SystemVerilog 包

文章出处:【微信号:Open_FPGA,微信公众号:OpenFPGA】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    [启芯公开课] SystemVerilog for Verification

    学快速发展,这些趋势你了解吗?SystemVerilog + VM是目前的主流,在未来也将被大量采用,这些语言和方法学,你熟练掌握了吗?对SoC芯片设计验证感兴趣的朋友,可以关注启芯工作室推出的SoC芯片
    发表于 06-10 09:25

    systemverilog学习教程

    systemverilog的一些基本语法以及和verilog语言之间的区别。
    发表于 04-01 14:24

    round robin 的 systemverilog 代码

    大家好,我对一个 round robin 的 systemverilog 代码有疑惑。https://www.edaplayground.com/x/2TzD代码第49和54行是怎么解析呢 ?
    发表于 03-14 19:16

    做FPGA工程师需要掌握SystemVerilog吗?

    在某大型科技公司的招聘网站上看到招聘逻辑硬件工程师需要掌握SystemVerilog语言,感觉SystemVerilog语言是用于ASIC验证的,那么做FPGA工程师有没有必要掌握SystemVerilog语言呢?
    发表于 08-02 20:30

    请问导入SystemVerilog程序意味着什么?

    导入SystemVerilog程序意味着什么?
    发表于 12-11 06:53

    SystemVerilog有哪些标准?

    SystemVerilog有哪些标准?
    发表于 06-21 08:09

    (2)打两拍systemverilog与VHDL编码 精选资料分享

    2打两拍systemverilog与VHDL编码1 本章目录1)FPGA简介2)SystemVerilog简介3)VHDL简介4)打两拍ve
    发表于 07-26 06:19

    SystemVerilog Assertion Handbo

    SystemVerilog Assertion Handbook1 ROLE OF SYSTEMVERILOG ASSERTIONSIN A VERIFICATION METHODOLOGY
    发表于 07-22 14:08 188次下载

    SystemVerilog的断言手册

    SystemVerilog Assertion Handbook1 ROLE OF SYSTEMVERILOG ASSERTIONSIN A VERIFICATION METHODOLOGY
    发表于 07-22 14:12 20次下载

    各种漆铜线简介与要求

    各种漆铜线简介与要求 一、聚乙烯甲醛漆铜线(PVF)
    发表于 04-09 10:04 113次下载

    Labview2013各工具的功能简介

    Labview2013各工具的功能简介Labview2013各工具的功能简介
    发表于 11-20 11:20 0次下载

    SystemVerilog的正式验证和混合验证

    手册的这一部分探讨了使用SystemVerilog进行验证,然后查看了使用SystemVerilog的优点和缺点。
    发表于 03-29 10:32 24次下载

    SystemVerilog中的struct

    SystemVerilog“struct”表示相同或不同数据类型的集合。
    的头像 发表于 11-07 10:18 2444次阅读

    SystemVerilog中的Shallow Copy

    SystemVerilog中的句柄赋值和对象复制的概念是有区别的。
    的头像 发表于 11-21 10:32 898次阅读

    FPGA学习-SystemVerilog语言简介

    SystemVerilog是一种硬件描述和验证语言(HDVL),它基于IEEE1364-2001 Verilog硬件描述语言(HDL),并对其进行了扩展,包括扩充了 C语言 数据类型、结构、压缩和非
    的头像 发表于 12-08 10:35 2142次阅读