一、 System Verilog 声明的位置
1. 包(packages)
Verilog要求局部声明:
variables, nets, tasks and functions的声明需要在模块内部的module...endmodule关键词之间
System Verilog 增加了用户定义类型typedef
i. 包的定义
包在packageand endpackage.之间定义。
包中可以包含的可综合的结构有:
•parameter and localparam constant definitions常量
•const variable definitions变量
•typedef user-defined types用户定义类型
• Fully automatic task and function definitions
•import statements from other packages
• Operator overload definitions
模块中的每个实例可以对parameter重新定义,但是包中不能。包中的参数不能重新定义
Example: 一个包的定义
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 //包定义结束
ii. 引用包的内容
模块和接口可以用四种方式引用包中的定义和声明:
1. 用范围解析操作( :: )直接引用
2. 将包中特定子项导入(import)到module or interface
3. 将通配符导入包中的子项到module or interface
4. 将包中子项导入到$unit声明域中
For 1:
module ALU
(input definitions::instruction_t IW, //用范围解析操作符::引用definitions包中的instruction_t结构体,并对其命名为IW
input logic clock,
output logic [31:0] result
);
always_ff@(posedgeclock) 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
For 2:
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导入方式是将每个子项逐个导入,在有许多子项需要从包中导入时并不实用,此时使用通配符导入会更实用。