systemverilog(三)过程语句与子程序

过程语句
systemverilog可以在for循环中定义循环变量,它的作用范围仅限于循环内部,从而避免一些代码漏洞。自动递增符”++“和自动递减符”–“既可以作为前缀,也可以作为后缀;如果在begin或fork语句中使用标识符,那么在相应的end或join语句中可以放置相同的标号。也可以把标号符放在sv的其他结束语句,例如endmodule、endtask、endfunction

initial
	begin:example
	integer array[10],sum,j;
	for(int i=0;i<10;i++)
	array[i]=i;
	sum=array[9];
	do
	sum+=array[j];
	while(j--!=0);
	$display("sum=%d\n",sum);
	end:example

systemverilog,第一个continue,用于在循环中跳过本轮循环而直接进行下一轮循环;第二个是break,用于终止并跳出循环。

任务、函数以及void函数
任务(task)和函数(function)区别最重要的一点,任务可以消耗时间而函数不能。函数里面不能带有诸如#100的时延语句或诸如@(posedge clock、wait(ready)的阻塞语句,也不能调用任务;而且函数必须有返回值,并且返回值必须被使用,例如用到赋值语句中。
(如果你有一个不消耗时间的systemverilog任务,应该把它定义成void函数,这样被任何任务或函数所调用了)
在这里插入图片描述
有些仿真器,如VCS,可以在不使用上述void的情况下忽略返回值
1、在子程序去掉begin…end(task/endtask和function/endfunction已经足够定义这些子程序的边界)
2、verilog对参数处理方式,在子程序的开头把input和inout的值复制给本地变量,在子程序退出时则复制output和inout的值,在systemverilog中,参数的传递方式可以指定为引用而不是复制
在这里插入图片描述

  • systemverilog规定ref参数只能被用于带自动存储的子程序中,如果指明automatic属性,则整个子程序内部都是自动存储的
  • 向子程序传递数组时应尽量使用ref以获得最佳性能,如果不希望子程序改变数组的值,可以使用const ref类型
  • 在任务里可以修改变量而且修改结果对调用它的函数随时可见)

3、参数的缺省值
在systemverilog中,可以为参数指定一个 缺省值,如果在调用时不指明参数,则使用缺省值。

function void print_checksum(ref bit [31:0] a[],
												input bit [31:0] low=0;
												input int high=-1);
bit [31:0] checksum=0;
if(high==-1||high>=a.size())
high=a.size()-1;
for(int i=low;i<=high;i++)
checksum+=a[i];
$display("The array checksum is %0d",checksum);
endfunction

4、采用名字进行参数传递
任务或函数的参数被称为port,类似于模块的接口
例如:

task many(input int a=1,b=2,c=3,d=4);
	$display("%0d %0d %0d %0d,a,b,c,d);
	endtask
	initial
	begin
	many(6,7,8,9);//6,7,8,9
	many(,6,.d(8));//1,6,,3,8

5、常见代码错误
(在缺省的情况下参数的类型是与前一个参数相同,第一个参数缺省类型单比特输入,而在子程序中使用非缺省输入类型的参数,应该指明所有参数的方向)

子程序的返回
1、返回语句
增加return语句

2、从函数中返回一个数组

  • 定义一个数组类型,然后再函数声明中使用该类型,但是函数init创建一个数组,该数组的值被拷贝到数组f5中。
    在这里插入图片描述
  • 通过引用来进行数组参数的传递
    在这里插入图片描述
  • 将函数包装在一个类中,然后返回对象的句柄

使用auomatic修饰符,使局部变量位于不同的存储空间,所以可以对一个任务同时进行多次调用(如果没有,由于第一次调用处于等待状态,第二次调用会覆盖任务的参数);而且局部变量在仿真开始前就被赋初值,解决方案是避免在变量声明中赋予除常量以外的任何值。
在这里插入图片描述
(由于local_addr是静态分配,在仿真开始就被赋值,而不是进入块中)
只需将程序块声明为automatic即可。
或者将声明与初始化分开

时间值
使用timeunit和timeprecision声明语句可以为每个模块指明时间值,注意如果使用这些语句代替了timescale,必须把他们放在每个带有时延的模块中。
verilog时间函数timeformat的四个参数分别是时间标度(-9纳秒),小数点后的数据精,时间值之后的后缀字符串,已经显示数值的最小宽度
在这里插入图片描述
可以将时间值存放在变量中,并在计算和延时中使用。根据当前的时间精度,时间值会缩放或舍入。有time类型是64bit的证书,可以采用real型变量存储,(
$time返回舍入后的整数, $realtime 返回一个实数)
在这里插入图片描述

发布了64 篇原创文章 · 获赞 5 · 访问量 3203

猜你喜欢

转载自blog.csdn.net/buzhiquxiang/article/details/104000737