下面的例子中使用的makefile:
dumpfile:
一、不使用pkg的filist
1.首先filelist(tb.f)中如果只是包含文件夹,不是指定包含文件。
比如我们有三个文件在同一个文件夹下:
第一个lab_task.sv,里面只包含了一个task print_t,但是这个task使用,lab_task0.sv里面定义的print_i task。
第二个lab_task0.sv,也只定义一个task
第三个就是一个testbench的文件,注释部分先不用看。这里面只是调用了print_t这个task。
filelist我们这样写:注释的部分不用看(//)
此时lab_task.sv和lab_task0.sv是没有包含出来,只是列举了包含他们的path ./。但是lab28_dpi是列出来的,编译结果是:
可以看到 ,编译找不到print_t,那么我们就需要显示的将lab_task.sv和lab_task0.sv包含进去。显示包含有两种方式:
第一种方式是直接在filelist中。将两个文件列出来,需要注意文件顺序。(这里其实+incdir+./可以不要,因为我们需要的两个文件已经列出来)
编译结果就不会报错:
第二种就是tb.f不变,但是在lab28_dpi中将两个文件`include进来。这种也不会报错(但是注意+incdir+./不能省略,因为可能lab_task可能和testbench不在同一个文件夹下,所以需要指明路径,这里省略是因为在同一个目录下)。
如果两种方式同时使用就会报重复编译错误,也就是如果filist列举出来,那么就不用include进去(这种情况可以使用宏来避免)。
2.如果文件不在同一文件夹下。
如果我们把lab_task.sv和lab_task0.sv放在上一级目录,filist为:
testbench依然为:
编译报错,找不到对应的lab_task.sv,和lab_task0.sv:
这说明我们需要把这两个文件显示的包含进来,和上面一样,也是上面这两种方式:
首先说第二种include方式,我们可以在testbench的include上加上路径,`include "../lab_task.sv" ,`include "../lab_task0.sv",这样也会编译出结果,但是这种不常用。常用的是tb.f中加上上一级目录,同时testbench中include不变。也就是只需要把tb.f改为:
第一种方式在filist中加上这两个文件申明,就是加上两行../lab_task.sv,../lab_task0.sv。但是就别既在filist中加文件,又在testbench中加include。比如我们两种都使用,那么就会报错:
(如果想要避免这种错误,可以使用宏定义来控制)。
二 在filelist使用pkg(作用是避免过多使用`include或在filelist中放入过多条目)
1.不能将pkg在module内部中`include。也不能在pkg内`include "pkg"。还有也不能在pkg内`include "interface.sv"。
比如,下面两种都会报错
module test()
`include "pkg1.sv"
endmodule
package pkg1;
`include "pkg2.sv"
endpackage
正确的应该是在外面`include(因为include就是把代码段嵌入include处),在里面import。比如
`include "pkg1.sv"
module test();
import pkg1::*;
endmodule
2.filist中加上pkg
比如我们现在用一个pkg将两个task文件包进去(此时lab_task.sv,lab_task0.sv,lab_pkg.sv都在目录../下,而makefile,filelist,testbench都在./(当前目录) ),文件内容如下(注释部分先不去管):
此时,我们也可以使用两种方式来使用pkg.
第一种,也是在filist中将其列出来(注意一般都需要将所在目录加上,因为有依赖文件,比如lab_pkg.sv依赖lab_task.sv和lab_task0.sv,所以..incdir+../需要加上):
然后直接在testbench中去import(注意就不用`include了,否则重复编译) 。
编译结果:
第二种,不在fileist中将lab_pkg列出来,然后在testbench中使用include和import来使用lab_pkg.此时filelist为:
testbench为:
2.嵌套的package以及非嵌套package。
比如现在lab_pkg.sv只包含lab_task.sv,lab_pkg0.sv只包含lab_task0.sv,两个pkg的内容如下。
如果我们filelist如下:
testbench如下:
那么编译会报错:
因为lab_pkg0没有include进来。
我们可以在lab_pkg.sv中将lab_pkg0.sv include进去。入下修改lab_pkg.sv为:
这样编译就不会报错:
但是这样嵌套使用,如果我在testbench中想直接使用print_i是使用不了的。因为对嵌套使用的pkg里的内容对于testbench是不可见的。比如testbench改为:
会报错找不到print_i:
要想在testbench上也可以直接使用print_i,这里举三种方式:
A.一种是print_i所在的lab_task0.sv不使用pkg来打包,而是直接include 进入lab_task0.sv。这样就不是期嵌套的使用pkg,而是直接include的一个文件,那么print_i对于testbench就是可见的(其他文件不变)。代码如下:
但是注意不可在pkg定义外面include,这样也会报错的,lab_task会找不到print_i。
错误示范:
编译报错:
但是注意这种情况对于testbench来说,print_i是可见的,比如我们将上面报错地方lab_task.sv中对print_i注释掉。其他代码保持如上:
编译结果不会报错:
B. 上面错误示范情况知道,pkg外include的文件内容可以在其他地方使用(也就是一地include,多地使用),但是对于pkg内的是不可见(如果pkg外include是pkg文件,则需要在pkg内加上对此include文件的import才可以),所以可以lab_pkg不变,tb.f也不变,只需在testbench中加上import lab_pkg0::*就可以(这里就是一次include pkg文件,多地import)。
编译结果,print_i执行两次:
C.另种是可以直接在filist中加上../lab_pkg0.sv这一行,然后lab_pkg.sv中取消掉`include "lab_pkg0.sv"(避免重复编译),同时testbench上加上,import lab_pkg0::*这一行,就可以了。文件内容如下:
filelist:
lab_pkg:
testbench(注意lab_pkg.sv在testbench中做了include,如果不想include需要在filelist中列出lab_pkg.sv):
编译结果:
总结来说:规则是,要想使用某个文件内容,要么将文件在filelist中列出来,要吗include进去(filelist中列出相应文件夹)。嵌套的pkg只对于当前pkg中内容可见。pkg需要import。