在从事IC验证工作的过程中,其实最开始的一步不是写什么test plan或者说verification of structure,而是应该知道makefile怎么写,先写出一个通用,基础的编译仿真脚本,可能会让你编译仿真轻松一点。
这份Makefile使用教程仅是基础版,不涉及复杂编译环境
一、VCS编译的四个步骤
预处理—>编译—>汇编—>链接
1、预处理(Pre-processing):
先将Verilog/SystemVerilog文件转化为C文件
2、编译:
生成目标文件
3、链接:
生成可执行文件
二、程序的编译和链接
要得到最后可执行的程序,首先要把源文件编译成中间代码文件,在Windows 下也就是 .obj 文件,UNIX\Linux 下是 .o 文件,即Object File,编译(compile)。再把大量的Object File 合成执行文件,链接(link)。
编译时,编译器需要的是语法正确,函数与变量的声明正确。对于后者,通常是你需要告诉编译器头文件的所在位置,只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件(O 文件或是OBJ 文件)。
链接时,主要是链接函数和全局变量。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File)。
在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,通常要给中间目标文件打个包,在Windows 下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX 下,是Archive File,也就是 .a 文件。
三、Makefile 是什么
GNU make是一个命令工具,是一个用来控制软件构建过程的自动化管理工具。Make工具通过称为Makefile的文件来完成并自动维护编译工作,由Richard Stallman 与Roland McGrath设计开发 。
Makefile是用于自动编译和链接的,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是所有的文件都需要重新编译,Makefile中记录有文件的信 息,在make时会决定在链接的时候需要重新编译哪些文件。
make命令格式:make [-f Makefile] [option] [target]
在terminal中可以敲入以下命令:
#make target #make #make clean (伪目标)
Makefile的宗旨就是:让编译器知道要编译一个文件需要依赖其他的哪些文件。当那些依赖文件有了改变,编译器会自动的发现最终的生成文件已经过时,而重新编译相应的模块。
makefile带来的好处就是—“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
四、Makefile的使用
4.1 Makefile的文件名
默认的情况下,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件,找到了解释这个文件。在这三个文件名中,最好使用“Makefile”这个文件名,因为,这个文件名第一个字符为大写,这样有一种显目的感觉。最好不要用“GNUmakefile”,这个文件是GNU的make识别的。有另外一些make只对全小写的“makefile”文件名敏感,但是基本上来说,大多数的make都支持“makefile”和“Makefile”这两种默认文件名。
当然,你可以使用别的文件名来书写Makefile,比如:“Make.Linux”,“Make.Solaris”,“Make.AIX”等,如果要指定特定的Makefile,你可以使用make的“-f”和“–file”参数,如:make -f Make.Linux或make --file Make.AIX。
4.2 Makefile里有什么
Makefile里主要包含了五个东西:显式规则、隐含规则、变量定义、
文件指示和注释。
1、显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由
Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
如: foo.o : foo.c defs.h 依赖关系
gcc -o foo.o foo.c 生成目标的方法(方式)
2、隐含规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让
我们比较粗糙地简略地书写Makefile,这是由make所支持的。
如: foo.o : foo.c (.o文件自己推导出同名的依赖文件.c.)
3、变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点像C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
如:H: =foo.c gcc -o foo.o $(H) (赋值可以用: =也可以直接用 =)
4、文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。
5、注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++,Java中的“//”一样。
在Makefile中的命令,必须要以[Tab]键开始。
4.3 定义变量和引用变量
变量的定义和应用与Linux环境变量一样,变量名要大写,变量一旦定义后,就可以通过将变量名用圆括号括起来,并在前面加上“$”符号来进行引用。
变量的主要作用:
1、保存文件名列表
2、保存可执行命令名,如编译器
3、保存编译器的参数
变量一般都在makefile的头部定义。按照惯例,所有的makefile变量都应该是大写。
4.4 Makefile的规则
target … : dependencies …
command
…
target也就是一个目标文件,可以是Object File,也可以是执行文
件。还可以是一个标签(Label)。
dependencies就是依赖文件,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。(任意的Shell命令,可以有若干行)
Command必须以Tab键开头。否则,make就会显示出错信息。如果某一命令行太长可以分作两行,用反斜杠(\)连接。也可以跟目标和依赖文件在一行,不过要以 ; 隔开。
在makefile执行时,make 带有参数“-n”或”-just-print”,那么其就只会显示命令,不执行命令。这个功能有利于我们调试Makefile,看看我们书写的命令执行起来是什么样子的或是什么顺序的。
4.5 伪目标
目标“.PHONY”的所有的依赖被作为伪目标。伪目标时这样一个目标:当使用make命令行指定此目标时,这个目标所在规则定义的命令、无论目标文件是否存在都会被无条件执行。
五、Makefile仿真
VCS对verilog模型进行仿真包括两个步骤:
-
编译verilog文件成为一个可执行的二进制文件
-
运行该可执行文件:./simv
以下是其他博主做的vcs命令的整理,在这里就不再赘述了,有需要请自行查看
vcs编译命令
vcs仿真命令
5.1 Makefile example
在每一行前面需要加上tab,而不是空格,不用tab会报错
.PHONY : comp sim clean
//当使用make命令行指定此目标时,这个目标所在规则定义的命令、无论目标文件是否存在都会被无条件执行。
PROJECT = xxx
UVM_VERBOSITY = UVM_LOW
DEBUG = -debug/-debug_all/-debug_pp (在这里可以对debug的命令进行选择)
-debug —— (对应TB中的$vcdpluson加载波形函数)使能DVE、VERDI波形调试和UCLI命令行调试等;
-debug_all —— 使能所有的debug调试功能;
-debug_pp —— 同-debug_all,但是更加节约资源;
CM_PATH = XXX 指定覆盖率文件放置的路径
comp :
(tab) vcs \
(tab) -ucli \ 使能UCLI命令
(tab) -lca \ vcs参数,表示使用vcs“用户限制使用”功能,即vcs提供的一些功能,但该功能还未经过充分验证。
(tab) -kdb \ Knowledge Database (KDB),生成kdb.elab++,位于simv.daidir目录下
(tab) -sverilog \ 编译支持SystemVerilog语法;
(tab) +v2k \ 编译支持Verilog—2001语法;
(tab) -timescale=time_unit/time_precision \ 添加仿真时间单位、精度;
(tab) $(DEBUG) \
(tab) -ntb_opts uvm \ —— 常用参数uvm,这里表示加载uvm库文件
(tab) -f filename \ —— 指定源文件的路径名列表
(tab) -cm line|cond|fsm|tgl|branch|assert —— 覆盖率收集,常用命令 -cm line+cond+fsm+tgl
(tab) -cm_dir $(CM_PATH) \ —— 指定覆盖率文件放置的路径
(tab) +vcs+lic+wait \—— 当所有的license都不可用时,等待vcs的license
(tab) -full64 \ 以64位模式编译设计并创建64位可执行文件用于64位模式下的模拟,如果不加上这个option,在仿真时,当出现内存超过4GB时,仿真会停止,但出现内存超过4GB可能是正常现象。
(tab) -o $(PROJECT) \ ——指定编译后产生的文件名,默认编译后的文件名为simv,在这为PROJECT指定的名字
(tab) -l compile.log \ 生成编译的日志
sim :
(tab)./simv \
(tab)+fsdb+autoflush \ # 命令行参数autoflush,一边仿真一边dump波形,如果没有该参数,那么不会dump波形,需要在ucli命令run 100ns后键入fsdbDumpflush才会dump波形
(tab)-l sim.log
clean :
rm -rf *.log simv *.daidir csrc *.key DVEfiles *.vpd