基于Makefile实现VCS的编译仿真与Verdi的设计分析
目录1. VCS1.1. Elaborate / Complie Design例子1.2. Simulate with DVE-gui-ucli2. Makefile主要讲解如何在Linux环境下使用VCS对verilog或systemverilog进行编译,并使用VCS自带的DVE实现仿真和波形查看。同时为了方便操作,介绍如何使用makefile实现自动化操作。1. VCS全称Verilog C
目录
主要讲解如何在Linux环境下使用VCS对verilog或systemverilog进行编译,并使用VCS自带的DVE实现仿真和波形查看。
同时为了方便操作,介绍如何使用makefile实现自动化操作。
1. VCS
全称Verilog Compiler Simulator,是Synopsys家的
其实就类似于windows环境下的questasim或modelsim,只不过vcs是linux环境下的工具。
可参考
《vcsmx user guide》
《vcsmx unified command line interface(ucli) user guide》
《VCS_DVE中文用户手册》
VCS+Verdi 仿真教程
[VCS]VCS常用命令詳解
Linux 运行vcs仿真命令,VCS使用以及命令行调试
1.1. Elaborate / Complie Design
首先是编译,主要完成语法检查和文件联编,并生成可执行的仿真文件
可直接在Linux终端执行,格式如下:
vcs [选项] [文件]
其中选项是可选的,下面给出一些常用选项
-full64: 支持64位系统
-l [文件名]: 创建文件,用于记录编译日志
-f [文件名]: 在某文件中索引要编译的文件路径,以及其他编译选项
-o [文件名]: 重命名仿真文件
-debug_acc+all: 支持UCLI调试
+incdir+[目录]: 为`include指定索引目录
+define+[宏]: 宏定义
-notice: 更加冗长的编译信息,便于调试
-timescale=1ns/1ps:时间单位和时间精度
+v2k: 开启verilog 2001架构
-sverilog: 开启systemverilog 架构
注意*.v中的`include均是以Makefile文件 或 输入vcs命令为起点目录!!!
而不是*.v文件所在的目录!!!
啥意思?看例子!
例子
首先在sequence_check目录下,有一个files.f和目录exercise,目录exercise下有sequence_check_tb.v和sequence_check.v
各文件内容如下:
//*************files.f*******************
./exercise/sequence_check_tb.v
//****************sequence_check_tb.v******************
`timescale 1ns/1ps
`include "./exercise/sequence_check.v" //注意这里不能写成`include "sequence_check.v"
module sequence_check_tb();
//...
endmodule
//*******************sequence_check.v*************
module sequence_check();
//...
endmodule
然后执行编译,在sequence_check目录下写入
vcs -full64 -debug_acc+all -sverilog -l comp.log -f files.f
运行之后显示信息
并且在sequence_check目录下,多出来好几个文件,这里面的文件comp.log就是编译的日志,文件simv就是用于仿真的文件
1.2. Simulate with DVE
之后就可以使用DVE进行仿真了
命令格式
simv [选项]
选项如下
-l [文件]: 仿真日志
-gui: 开启GUI界面,否则就在linux终端显示transcript的内容
-ucli: 在linux终端使用TCL控制仿真进程
-i [文件名].tcl: 启动DVE后,在UCLI要启动的TCL命令
-gui
开启图形界面模式,要看波形必须得开这个,这个界面就很类似于questasim了
那么怎么看波形呢,首先需要add dump一下,才能看数组、结构体这种
将选中信号,然后add wave→new wave就开启DVE看波形了,对波形的简单操作如下
-ucli
这样就可以在linux终端下使用tcl命令控制仿真,在图形界面中的下面也可以使用ucli模式对仿真进行控制
在ucli中一些tcl命令如下
scope: 显示当前的顶层模块
scope u1: 就表示进入到当前顶层模块中的u1模块,同时将u1模块设置为顶层模块
scope -up: 回到目前顶层模块的上一层。
show: 显示当前顶层模块的信号以及子模块
show -value 信号 -radix hex/bin/dec:显示信号的值 以特定的进制显示。
run:运行仿真run 一直运行,直到遇到$stop或者设置的断点
run time: 运行多少时间停止(不推荐)
run -posedge: 信号 运行到信号的上升沿停止
run -negedge: 信号 运行到信号的下降沿停止
run -change: 信号 信号有变化时停止
stop: 设置断点stop 显示断点
stop -posedge: 信号 在信号的上升沿设置断点
stop -negedge: 信号 在信号的下降沿设置断点
stop -condition {信号表达式}: 信号表达式为真的地方设置断点
stop -delete 断点值: 删除断点值的断点
restart: 重新开启ucli调试模式
call {系统任务}:调用verilog系统任务,
finish:结束仿真
force:信号强制赋值
release:解除信号强制赋值
get:获取信号数值
step:单步执行
do *.do:可将很多这些UCLI命令整合到一个*.do文件内,然后以打包运行
命令 –h:显示命令的帮助
以上这些命令完全可以配合一般的tcl命令一起使用,例如
set i 0;
while {$i < 20} {
force top.clk 1;
run 10ns;
force top.clk 0;
run 10ns;
incr i 1;
}
release top.clk;
2. Verdi
一开始我还不理解,人家VCS既能编译,又能仿真出波形,还要Verdi干嘛?
后来才了解到,Verdi是在编译、仿真出波形之后,用来分析工程的。
除了原理图,波形,状态机图和波形比较等基本功能,Verdi还可以自动跟踪信号活动、基于断言的调试、功耗感知调试以及事务和消息数据的调试和分析等等。
下面介绍一下常见功能
2.1. 启动
首先是启动,依据*.v和testbench建立工程
可直接在Linux终端执行,格式如下:
verdi [选项] [文件]
其中选项是可选的,下面给出一些常用选项
-f [文件名]: 在某文件中索引工程包含的文件路径
-top [名称]: 工程名称,建议用testbench的名字
-nologo: 无欢迎界面
-ssf [文件名].fsdb: 指定已有的波形文件
2.2. 打开波形 nWave
先是打开波形。Verdi识别*.fsdb波形文件,所以在使用VCS执行仿真的时候,要输出*.fsdb波形文件
如何输出呢?在UCLI使用call的TCL语句调用系统函数,比如
call {$fsdbDumpon}: 打开波形保存功能
call {$fsdbDumpoff}: 关闭波形保存功能
call {$fsdbDumpfile("dump.fsdb")}: 指定波形文件名为dump.fsdb
call {$fsdbDumpvars(0,addr4_tb,"+all")}: addr4_tb为指定的testbench,0表示输出所有层次的波形,1表示只输出第一层的波形,以此类推,"+all"表示输出结构体等数据结构
然后再启动verdi时指定那个fsdb文件就可以打开波形了
2.3. 信号追踪 nTrace
2.4. 架构查看 nScheme
3. Makefile
作用也是整合linux命令,将所有命令写到一个名为Makefile的文件下,然后在终端输入make xxx即可运行对应的命令
例如有个Makefile文件内容如下,注意使用\表示同一组代码
在该Makefile的目录下执行以下命令及含义为:
make all
:等价于make clean
之后再make comp
make comp
:执行后面的linux命令,表示使用vcs编译,并生成仿真文件
make run
: 运行仿真
make rung
:以gui形式运行仿真
make clean
:看到rm -rf就是删除文件,其实就是清除上一次编译仿真留下来的文件
当然Makefile也支持变量替换,如同TCL那样
#############################
# User variables
#############################
TB = apb_tb
SEED = 1
TESTNAME ?= apb_single_transaction_test
VFILES += apb3_pkg_ref/{apb_pkg.sv,apb_tb.sv}
#############################
# Environment variables
#############################
VCOMP = vlogan -full64 -ntb_opts uvm-1.2 -sverilog -timescale=1ps/1ps -nc -l comp.log +incdir+apb3_pkg_ref
ELAB = vcs -full64 -ntb_opts uvm-1.2 -debug_all -l elab.log -sim_res=1ps
RUN = $(TB).simv -l run.log -sml +ntb_random_seed=$(SEED) +UVM_TESTNAME=$(TESTNAME)
comp:
$(VCOMP)
$(VCOMP) $(VFILES)
elab: comp
$(ELAB) -top $(TB) -o $(TB).simv
run:
$(RUN)
rung:
$(RUN) -gui
clean:
rm -rf AN.DB DVEfiles csrc *.simv *.simv.daidir *.simv.vdb ucli.key
rm -rf *.log* *.vpd *.h urgReport
所以可以用cd ./vcs && ./run_vcs.sh
来切换目录并启动新目录下的命令
通过下一节工程目录结构,查看写法。
4. 工程目录结构
这里给出一个典型的工程目录结构,以使层次更加分明
rtl目录
用于存放各种*.v文件,除了testbench文件
tb目录
用于存放各种*.sv格式的testbench文件
tb文件就不用再include涉及到的*.v文件了
vcs目录
用于只存放编译文件,必要文件有
file.list
列出编译所需的全部rtl和tb文件,注意…表示以rtl目录的上级目录
例如
//rtl files
../rtl/uart_tx.v
../rtl/uart_rx.v
../rtl/uart.v
//tb files
../tb/uart_tb.sv
macro.list
主要包括宏定义、库文件的Verilog模型路径,文件搜索路径信息等。
//macro
+define+UART_HIGH_BPS
+define+UART_FIFO_DEPTH = 4096
//指定库文件,建议包含路径
//-v <filename>
//指定库文件,IP等Verilog模型路径
//-y <directory>
//指定要包含的文件目录
//+incdir+<directory>
run_vcs.sh
用于启动VCS编译,注意将刚才的file.list和macro.list添加进去
注意使用\换行
-top 命令后接的是tb文件的Module名字
vcs -full64 -notice -debug_all+acc -j8 \
+plusarg_save +libext+.v+.V+.sv+.svh -sverilog +memcbk \
-P ${Verdi_HOME}/share/PLI/VCS/LINUX64/novas.tab \
${Verdi_HOME}/share/PLI/VCS/LINUX64/pli.a \
-cpp /usr/bin/g++-4.4 -cc /usr/bin/gcc-4.4 \
-f ./file.list -f ./macro.list -top uart_tb \
-l ./compile.log
sim目录
此处添加仿真、波形生成命令,并开启Verdi进行调试
wave_gen.tcl
这个是打开DVE之后,要输入的UCLI命令,整理在这里然后自动调用
call {$fsdbDumpfile("dump.fsdb")}
call {$fsdbDumpvars(0, uart_tb, "+all")} //uart_tb是tb文件的module名字,不是乱起的!!!!
call {$fsdbDumpon}
run
run_sim.sh
启动仿真。由于编译后生成的simv和sim.daidir在vcs目录下,所以这里需要搞个快捷方式
ln -sf ../vcs/sim* .
simv -ucli -i ./wave_gen.tcl -l ./sim.log +fsdb+function
run_verdi.sh
启动verdi
verdi -f ../vcs/file.list -f ../vcs/macro.list -top uart_tb -ssf ./dump.fsdb -nologo &
Makefile文件
方便终端直接运行各目录下的文件,而不用在目录之间跑来跑去,所写的Makefile如下
all: clean comp run verdi
comp:
cd ./vcs && ./run_vcs.sh
run:
cd ./sim && ./run_sim.sh
verdi:
cd ./sim && ./run_verdi.sh
clean:
rm -rf ./vcs/simv.* ./vcs/simv* ./vcs/csrc ./vcs/*.log
rm -rf ./sim/*.log ./sim/*.vpd ./sim/ucli.key ./sim/*.fsdb
要注意一切文件中的一切路径,都以指令所在目录为原点
例如tb目录下的uart_tb.sv中要访问外部数据,执行
$readmemh('init_mem.hex',uart_tb.u_uart.mem);
,那么这个init_mem.hex
文件应该放在哪里?
应该放在sim目录下,因为仿真是在该目录下启动,所以就以sim为目录原点搜索init_mem.hex
clean是为了删除全部的自动生成文件
写完之后,在makefile目录下执行对应的命令即可
更多推荐
所有评论(0)