SystemVerilog中package(包)的介绍
一、包的定义:
package 包名;
endpackage
包是一个独立的声明空间,多个模块共享用户定义类型。
二、包中可包含的可综合的结构:
1)parameter和localparam 常量定义;
2)const定义变量为常数;
3)typedef用户定义类型;
4)automatic task、function定义(必须申明为automatic,每次调用时将分配存储区,便于综合);
5)从其它包中import语句;
6)操作符重载定义。
三、包的引用方式:
1)用范围解析操作符
::
直接引用;
2)将包中特定子项导入到模块或接口中;
3)用通配符*
导入包中的子项到模块或接口中;
四、举例:
package definitions;
parameter Version = "1.1";
typedef enum {ADD,SUB,MUL} opcode_t;
typedef struct{
logic [31:0]a,b;
opcode_t opcode;
} instruction_t;
function automatic [31:0]multiplier(input [31:0]a,b);
return a*b;
endfunction
endpackage
直接引用方式:
module ALU( input 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::SUB:result = IW.a-IW.b;
definitions::MUL:result = definitions::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:: 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导入代码,可以使用下面testbench
中的import definitions:: *;
代替,也即一次性将所有子项导入,然后就可以直接使用如ADD
,而不用写成definitions::ADD
。
import definitions::*;
module tb_ALU;
instruction_t test_word ;
logic [31:0] alu_out;
logic clock = 0;
ALU dut(.IW(test_word), .result(alu_out), .clock(clock));
always #10 clock = ~clock;
initial begin @(negedge clock)
test_word.a = 5;
test_word.b =7;
test_word.opcode = ADD;
@(negedge clock)
$display(“alu_out = %d (expected 12)”, alu_out);
$finish;
end
endmodule