1.package 定义及从package中导入定义(***)

verilog中,对于变量、线网、task、function的声明必须在module和endmodule之间。如果task被多个module引用呢?

verilog用include解决,systemverilog借用VHDL的package解决。

@1: package可以包含的可综合的结构有:

1.parameter和localparam常量定义

2.const变量定义

3.typedef 用户自定义类型

4.全自动task和function定义

5.import语句

6.操作符重载定义

eg: package definition;

parameter VERSION = "1.1";

typedef enum{ADD,SUB,MUL} opcodes_t;

typedef struct{

logic [31:0]a,b;

opcodes_t opcode;

}instruction_t;

function automatic [31:0] multipler(input[31:0]a,b);

return a*b;

endfunction

endpackage

@2:package 内容引用方式:

1.使用范围操作符::

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

2.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_ff @(posedge clock) 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 // import definitions::opcodes_t; ?

endmodule

3.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;

SUB: result = IW.a – IW.b;

MUL: result = multiplier(IW.a, IW.b);

endcase

end

endmodule

 通配符导入并不自动导入整个package,只是相当于添加了一条搜索路径!!

4.将子项导入$unit中

import definitions :: instruction_t;

module ALU (input instruction_t iw, input logic clock; output logic [31 : 0] result);

package也可以通过通配符导入到$unit域中。通配符导入只是将package加到SystemVerilog源路径中!!

2.$unit编译声明空间

不要在$unit空间进行任何声明,所有共享的声明都要在package中。

需要时,可以将package导入到$unit中。

声明过于分散,结构乱,逻辑差,不利于调试。

3.未命名块中的声明

块命名后可以层次化引用其中变量,但不可以综合。

4.增强的时间单位定义

1. 包含时间单位的时间值:

forever #5ns clock = ~clock; //时间值与单位之间不能有空格!!

2. 使用关键字timeunit和timeprecision:

module adder(input wire[63 : 0] a, b, output reg [63 :0] sum, output reg carry);

timeunit 1ns;

timeprecision 10ps;//是模块的一部分,

……                       //而不是作为软件工具的指令

endmodule

timeunit和timeprecision使模块、接口或程序块与时间单位和精度信息直接绑定,

解决了timescale存在的不确定性和对文件顺序的依赖性。

它必须在其它声明或语句之前,紧随模块、接口或程序的声明之后。

timeunit和timeprecision的声明可以在编译单元域中,但必须在其它声明的前面。

05-15 15:13