SystemVerilog声明的位置(二)

本文介绍了Verilog中函数的局限性和SV中的包结构,包括全局参数、类型和任务函数定义,强调了包中变量的共享特性以及VCS和Vivado中包引用的位置差异。讲解了如何通过`include`引入条件编译以解决包导入问题,以及在不同编译域中的优先级规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 在Verilog中不能定义全局的函数,如果多个设计中要用到,只能在每个设计文件中定义。SV中提供了包,可以定义公共或全局的参数(parameter,localparame和const),自定义类型,任务和函数(前面必须要加automatic,个人理解:非共享的,每次例化会单独分配一块电路资源),但是不要在在包中定义变量,因为包中变量为所有导入变量的文件所共享(可以理解为软件里的静态变量)。为了更容易识别出文件的类别,包文件最好以.pkg作为后缀名。定义好之后,在需要使用的module文件中import包就可以了。如果没有import包文件,那么直接在module中使用的时候,需要加上包名(如图2)。

图1:
在这里插入图片描述
图2:
在这里插入图片描述

  1. 如果每次引用的时候都需要加上包名太繁琐了,那么就需要在module的前面加上import。但是VCS和Vivado中引用package有一些区别,如果在模块端口列表中使用包中的成员,那么import的位置在两个编译工具中有所区别,请看下面代码。
// 这段代码在VCS中能编译通过,在Vivado中编译不通过
import package_name;
module module_name
(
	// DATA_WIDTH来自于包里
	input logic [`DATA_WIDTH-1,0] dint
);

endmodule
// 在Vivado中需要修改下import的位置
module module_name import package_name;
(
	// DATA_WIDTH来自于包里
	input logic [`DATA_WIDTH-1,0] dint
);

endmodule
  1. 编译的优先级顺序:模块或接口内的局部定义和声明优先于导入包中指定的子项,导入包中指定的子项也优先于通配符导入。

  2. 将同样的包中子项多次导入到同一编译域中是非法的,为了避免这种情况,可以使用条件编译,使第一次遇到导入语句时将其编译到域中,而再次出现则不编译这些语句。特别是当多个文件中都需要某个包文件中定义的子项,进行多文件编译时,这种条件编译的方式保证只进行一次编译并导入到所有模块共享的公共$unit编译域中。
    图3:
    在这里插入图片描述

// 如果要引用上面的包,就不能用import了,因为上面不仅仅是包文件,还有一些条件判断语句,只能用include把文件包含进来了
`include "definitions.pkg"
  1. 在编译单元域,也就是所有模块和接口定义的外面,可以综合的结构:
  • typedef用户自定义类型
  • 动态函数(前面加automatic)
  • 动态任务(前面加automatic)
  • parameter和localparame定义的参数
  • 包导入
  1. 仿真时间单位和精度:

在verilog中使用`timescale指令来指定时间单位和精度,不在RTL Code中的时间值后面加单位:

`timescale 1ns/10ps
forever #5 clock = ~clock;

但是systemverilog可以在Code里的时间值后面加上时间单位:

`timescale 1ns/10ps
forever #5ns clock = ~clock;

SystemVerilog也可以在模块内用时间单位和时间精度指令来指定,但是这两个指令必须在其他任何声明或语句之前,紧随模块,接口或程序的声明之后:

module module_name(...);
	timeunit 1ns;
	timeprecision 10ps;
	...
endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值