提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
刚学习sv的小白,哪里写的有问题评论区指出,万分感谢!
一、过程语句
- begin...end/fork...join 首尾可以使用标识符,ps:相当于起个名字,initial块也可以使用。示例如下:
//initial过程块起名example1 initial:example begin ... end // //begin...end起名example2 initial begin:example2 ... end:example2
二、任务、函数以及void函数
1.任务与函数的区别
-
任务(task)可以消耗时间,即可以带有延迟语句#time,@(敏感事件),wait(等待事件)等。可调用task和function - 函数(function)不能带延迟时间的阻塞语句,可以调用其他function,但与Verilog不能调用task不同,它可以在fork...join_none语句生成的线程中调用task(关于fork...join_none语句创建线程详见绿皮书7.1节)。
- 注意:如果task是不消耗时间的,那么就可以将它定义成void函数,这样它就可以被其他task和function调用
2.任务(task)
- 可以通过output,inout,或ref参数返回
2.函数(function)
- 参数列表(可以指定input,output,inout,ref)
- 可以不返回数值,返回类型为void
- 默认数据类型为logic,参数方向为input,位宽1位
- 只有数据变量可以在参数列表声明为ref参数类型
- 在声明是可以给入默认值的,这样在调用时若缺省参数传递值那么就会使用默认值
function <返回类型> <函数名> (参数列表)
三、任务和函数概述(一些SV区别其他语言的改进)
- 不带参数的task和function是可以不带()的。
- begin...end可以省略
四、子程序参数
- ref参数类型的参数传递是引用而不是复制,这句话我的个人理解就是说对变量的修改是可见的,一般参数的传递是将变量复制到堆栈区,对变量的操作不会影响它本身,而引用是在使用指向变量的地址,任何操作都会直接影响变量的值。
- 如果不想改变你引用的变量的值,那么就使用const ref参数类型
- 参数传递可以采用位置和名字两种方式。参考module和interface的例化
五、子程序的返回
- 返回语句(return),使用return语句能够提前返回
- 函数返回数组的两种方式:
一是定义一个数组类型,然后在函数声明中返回类型使用该数组。示例如下:
typedef int fixed_array5[5]; //创建数组类型fixed_array5,该数组类型由5个整型元素构成
fixed_array5[5] f5; //声明数组f5,类型为fixed_array5
function fixed_array5[5] init(int start); //声明函数init,返回值类型为fixed_array5
foreach (init[i])
init[i] = i + start;
endfunction
module tb;
initial begin
f5 = init(5);
foreach (f5[i])
$display("f5[%0d] = %0d",i,f5[i]);
end
endmodule
打印结果:
二是通过引用来进行数组参数的传递。示例如下:
function void init1(ref int f[5],input int start);
foreach (f[i])
f[i] = i + start;
endfunction
module tb;
int fa[5];
initial begin
init1(fa,5);
foreach (fa[i])
$display("fa[%0d] = %0d",i,fa[i]);
end
endmodule
书上的例子编译有错误找不差哪里有问题
翻页就是局部变量的知识点,试了一下
module automatic tb;
int fa[5];
function void init1(ref int f[5],input int start);
foreach (f[i])
f[i] = i + start;
endfunction
initial begin
init1(fa,5);
foreach (fa[i])
$display("fa[%0d] = %0d",i,fa[i]);
end
打印结果:
三是将数组打包到一个类中,然后返回对象的句柄。这里书上没有示例代码,以下代码是自己写的感觉不太对劲,请大佬指点。。。
class array5; //定义一个数组类
typedef int fixed_array5[5];
fixed_array5[5] f5;
endclass
array5 handle; //声明句柄
function void init (ref array5 handle,input int start);
handle = new();
....
endfunction
六、局部数据储存
- 局部变量(automatic),仅在其所在域使用
- 全局变量(static),伴随程序执行到结束都有效,不声明时默认为静态变量static
- 过程块中定义的变量跟随过程块的类型
- module和program块中的子程序缺省下使用静态储存(static)
- 使用动态储存需在子程序名字前加入automatic关键词
七、时间值
- timeunit时间量程/timeprecision精度 ----- 'timescale = 1ns/1ps
- 时间函数:
$timeformat(a,b,c,d):a--时间表度-9=ns/-12=ps;b--小数点后的数据精度;c--时间值后紧跟的字符串;d--显示数值的最小宽度
$time:返回当前时间值,按时间精度舍入整数
$realtime:返回当前时间值,实数带小数
- 时间变量:将时间值存放到变量中,time类型的变量不能保存小数时延,64比特整数。时延的小数会被舍入,若不想舍入可以采用real变量类型,但是在作为延时量时还是会被舍入。
'timescale=1ps/1ps module ps; initial begin real rdelay = 800fs; //0.800ps time tdelay = 800fs; //1.000ps $timeformat(-15,0,"fs",5); #rdelay; //延时1ps $display("%t",rdelay); //打印结果“800ps” #tdelay; //延时1ps $display("%t",tdelay); //打印结果“1000fs” end endmodule