SystemVerilog中package(包)的基本使用

包(package)的使用

package声明

SystemVerilog包提供了一种额外的机制,用于在多个SystemVerilog模块、接口、程序和检查器之间共享参数、数据、任务、函数、序列、属性和检查器声明。
包是显式命名的作用域,出现在源文本的最外层(与顶级模块和原语处于同一级别)。
其中,我们可以理解,其实package里包的就是一些数据的。像interface,module是不能定义在package中的。

包的作用

1、把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
2、如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
3、包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。由于包创建了新的命名空间(namespace),所以不会跟其他包中的任何名字产生命名冲突。使用包这种机制,更容易实现访问控制,并且让定位相关类更加简单。

补充:感觉System Verilog语言会将小的模块进行拆分,归类,每次创建一个执行一个任务数据包。这个包的大小会不同。但是感觉都是拆分的思想。

在package中引用数据

1)用范围解析操作符::直接引用;
2)将包中特定子项导入到模块或接口中,用import导入;
3)用通配符*导入包中的子项到模块或接口中;
注意这里导入后函数就是直接使用的,变量需要使用句柄加.的形式

定义一个包

实例:

package definitions;                             //定义一个包
  parameter VERSION = "1.1";                     //定义包中一个参数
  typedef enum{ADD, SUB, MUL} opcodes_t;         //定义包中枚举opcodes_t
  typedef struct {
    logic [31:0] a, b;
    opcodes_t opcode;							 //声明自定义类型变量
  } instruction_t;                               //定义包中结构体instruction_t
  function automatic [31:0] multiplier (input [31:0] a, b); //定义函数function,其中参数为a,b
    return a * b;                                // 用户定义的function代码从这开始
  endfunction                                    //function定义结束
endpackage                                       //包定义结束

使用范围解析操作符::直接引用

module ALU(
  input definitions::instruction_t IW, //用范围解析操作符::引用definitions包中的instruction_t结构体,并对其命名为IW
  input logic clock,
  output logic [31:0] result
);
  always_ff @(posedge clock) begin
    case (IW.opcode)
      definitions::ADD : result = IW.a + IW.b; //用范围解析操作符::引用definitions包中的枚举ADD
      definitions::SUB : result = IW.a - IW.b;
      definitions::MUL : result = definitions::
      multiplier(IW.a, IW.b);
    endcase
  end
endmodule

导入package中的子项import

module ALU(
  input definitions::instruction_t IW,
  input logic clock,
  output logic [31:0] result
);
  import definitions::ADD;        //用import导入definitions包中的枚举ADD
  import definitions::SUB;
  import definitions::MUL;
  import definitions::multiplier;
  always_comb begin                          
  case (IW.opcode)
   ADD : result = IW.a + IW.b; //前面导入包中特定子项后,该子项在模块/接口中可见,可直接使用
   SUB : result = IW.a - IW.b;
   MUL : result = multiplier(IW.a, IW.b);
  endcase
  end
endmodule

使用通配符*导入所有的定义名称import

module ALU(
  input definitions::instruction_t IW,
  input logic clock,
  output logic [31:0] result
);
  import definitions::*;             // 通配符导入。实际上是将包添加到标识符搜索路径中
  always_comb begin
  case (IW.opcode)
   ADD : result = IW.a + IW.b;    //引用ADD时,在definitions包中查找该名称的定义
   SUB : result = IW.a - IW.b;
   MUL : result = multiplier(IW.a, IW.b);
  endcase
  end
endmodule
  • 0
    点赞
  • 17
    收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:点我我会动 设计师:我叫白小胖 返回首页
评论 2
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值