1. 如何运行makefile脚本
makefile在当前目录:
b makemakefile不在当前目录:
b make ./script/makefile run642. makefile最核心的模版
目标: 依赖1 依赖2 依赖3 命令1 命令2 命令3注意:命令前面必须是【Tab 制表符】,不能是空格
举个例子:
vcs64: compile_dep file_list @echo "start vcs compile" vcs -full64 +UVM_VERBOSITY=medium ...执行顺序:先跑 compile_dep、file_list,全部完成,才执行 vcs 编译命令。
3. shell里面常用指令有哪些?
echo: 打印提示信息
echo "===== start VCS compile ====="ls:列出目录里面的文件
ls $(tc_dir) ls *.vcp:复制文件
cp rom.txt $(tc_dir)/rm:删除
rm -rf $(tc_dir)/simvpwd:打印当前所在路径
find:查找文件
#find 【搜索起点目录】 【匹配条件】 【动作】 find ./run_dir -name "sim.log" # 在 ./run_dir 下面找名字严格等于 sim.log 的文件 find . -name "tc*_log" # 找 tc开头、_log结尾的文件grep:过滤、查找关键字(抓 ERROR、FATAL、PASS/FAIL)
grep "ERROR" sim.log grep -i fatal sim.log # -i 忽略大小写date:获取时间、时间戳
date +%Y%m%d # 年月日4. makefile内置函数$wilcard
ifeq (A, $(wildcard A)) cp A ./ endifA是完整文件路径;
$(wildcard A):去看 A 这个文件有没有
5. 仿真常用指令
编译指令:vcs
运行仿真:执行 ./simv
-sverilog:开启 SystemVerilog(UVM 必须加)
-full64:64 位模式,现在项目标配
debug_all:全 debug,支持 Verdi 看波形
-f filelist.f:从 f 文件读取源码列表
+incdir+xxx:头文件 include 搜索路径
+define+XXX:宏定义
-cm line+cond+fsm+tgl:打开覆盖率收集
-l run.log:输出 log 文件
-top xxx(显式指定顶层)
# -timescale 全局时间精度,后仿/高速接口经常指定 vcs -timescale=1ns/1ps -f filelist.f # -cm 开启覆盖率(line cond fsm tgl branch)回归用 vcs -cm line+cond+fsm+tgl -cm_dir ./cov.vdb -f filelist.f # 指定随机种子,复现bug超级常用 ./simv +ntb_random_seed=12345 # 直接拉起verdi,仿真一边跑一边dump波形 ./simv -verdi # 把仿真日志单独输出到文件 ./simv -l sim.log # 直接加载文件列表看RTL代码 verdi -f filelist.f6. 覆盖率收集常用指令
编译加-cm开启覆盖率采集 → 跑 simv 仿真生成.vdb覆盖率数据库
line:行覆盖率,代码行有没有跑到
cond:条件覆盖率,if、&&、|| 判断的所有分支是否都走到
fsm:状态机覆盖率,状态、状态跳转
tgl:toggle 翻转覆盖率,信号 0→1、1→0 是否都翻转
branch:分支覆盖率,case、if else 分支
assert:SVA 断言覆盖率(断言是否触发成功 / 失败)
-cm_hier:后面跟一个文本配置文件,用来告诉 VCS哪些模块统计覆盖率、哪些模块排除。
举个例子:-cm_hier cov.cfg
其中cov.cfg可以是下面内容
# +tree :包含这个层次,统计覆盖率 # -tree :排除这个层次,不统计覆盖率 # 只保留DUT作为覆盖率统计对象 +tree tb_top.u_dut # DUT里面有些第三方IP不想统计,单独排除 -tree tb_top.u_dut.u_external_sram_ip -tree tb_top.u_dut.u_analog_model-cm_name:给本次仿真产生的覆盖率数据起一个标签名字,属于 VCS 编译参数(写在 vcs 编译命令,不是 simv 后面)
vcs -cm line+cond -cm_dir ./cov_case1 -cm_name $(TC_NAME) -top tb_top -f filelist.f跑完之后,在./cov_case1/这个 vdb 库里面,这一组覆盖率数据的名字就叫$(TEST_NAME)
覆盖率合并:
方案1:每个 case 单独一个 vdb
-cm_name ${TEST_NAME}_${SEED} -cm_dir ${SESSION_DIR}/coverage 每个 test/seed 都会生成独立目录,类似: run_seed1/coverage/simv.vdb run_seed2/coverage/simv.vdb run_seed3/coverage/simv.vdb # 新版urg(推荐,输出merge.vdb) urg -full64 -dir run_seed1/coverage -dir run_seed2/coverage -dir run_seed3/coverage \ -merge \ -out ./cov_merge.vdb \ 打开覆盖率的方法 verdi -cov -covdir ./cov_merge.vdb &方案2:编译一次 simv,多次跑仿真追加到同一个 vdb
vcs -cm line+cond -cm_dir ./cov_total7.一个常用makfile脚本
makefile脚本
TC= TB= MOD= MY_DF= IS_COV= TIME_SCALE=1ns/1ps SEED= `data +%N` CMD=busb -IP -P xxx -q queue_name ifeq($(IS_COV),1) cov_opt= -cm cond+fsm+tgl+branch+line -cm_heir $(VCS_COV) -cm_name $(TEST_NAME)_$(SEED) -cm_dir $(SESSION_DIR)/coverage endif SIM_LIST =+define+AXIM_AGENT_EN+RTLSIM_TRCB \ +define+$(MY_DF) \ +incdir+$(FILE_PATH)/$(TC_BRANCH)/$(MOD)/testcase/$(TC)/tc_vlg \ +incdir+$(FILE_PATH)/$(TC_BRANCH)/$(MOD)/tc_public_v \ +incdir+$(FILE_PATH)/tb/tb_$(TB) \ $(FILE_PATH)/tb/eda/tb_top.v \ -f $(FILE_PATH)/tb/eda/tb_$(TB)/tb_$(TB).f ifeq "$(SIM_BRANCH)" "rtl" FILE_LIST= $(SIM_LIST) \ -f $(FILE_PATH)/tb/tb_$(TB)/rtl.f else endif ifeq "$(MY_DF)" "" tc_dir=$(TC)_$(MY_DF) else tc_dir=$(TC) endif cmp_opt= -full64 -debug_acc+pp+dmptf -debug_region=cell+encrypt +vcs+wait -sverilog -l vcs_cmp.log -top $(TOP_NAME) \ +notimingcheck -kdb \ $(cov_opt) \ +assert svaext \ -timescale=$(TIME_SCALE) sim_opt = +ntb_random_sees=$(SEED) -l vcs_run.log $(cov_opt)\ +fsdb+sva_success\ +fsdb+power mk_dir: @if [ -d $(tc_dir) ]; then \ echo $(tc_dir); \ else \ mkdir $(tc_dir); \ fi sim64: mk_dir cd $(tc_dir) && rm -rd simv* csrc *.txt ifeq (/path/$(MOD)/irom.txt, $wilcard(/path/$(MOD)/irom.txt) ) cp $(tc_dir) && cp /path/$(MOD)/irom.txt ./iram.txt endif cd $(tc_dir) && $(CMD) vcs $(cmp_opt) $(FILE_LIST) cd $(tc_dir) && $(CMD) ./simv $(sim_opt)如何调用这个makefile脚本?
set tc_num = 000 # 默认case号:000 if ( $#argv > 1 ) then # 判断:传入参数个数>1 echo "WRONG FILE! Please Input Again!" exit # 参数太多,报错退出 endif if ( $#argv == 1 ) then # 如果传了1个参数 unset tc_num set tc_num = $1; # 把传入的参数赋值给tc_num(就是testcase编号) endif b make -f ../script/makefile TB=... MOD=... TC=$tc_num vcs64 IS_COV=1