当前位置: 首页 > ds >正文

Makefile关键语法示例

Makefile关键语法示例

       摘要:本文50个Makefile关键语法示例,适用于UVM SoC验证环境:

基础语法和变量

# 1. 变量定义
TOP_DIR = $(PWD)
UVM_HOME = /tools/uvm-1.2# 2. 变量引用
SIM_DIR = $(TOP_DIR)/sim# 3. 条件赋值(仅在未定义时赋值)
SIMULATOR ?= vcs# 4. 立即赋值 vs 延迟赋值
IMMEDIATE := $(shell date)
DEFERRED = $(shell date)# 5. 追加赋值
VLOG_OPTS = +define+UVM_NO_DPI
VLOG_OPTS += -sverilog# 6. 多行变量
define RUN_TESTcd $(SIM_DIR) && \./simv +UVM_TESTNAME=$(TEST)
endef

目标和依赖

# 7. 基本规则
compile: rtl testbenchvcs -f filelist.f# 8. 伪目标
.PHONY: clean run all# 9. 多目标规则
rtl testbench: directories@echo "Building $@"# 10. 模式规则
%.sv: %.sv.templatesed 's/@@VERSION@@/$(VERSION)/g' $< > $@

递归调用

# 11. 递归Make
subsystem:$(MAKE) -C sub_blocks all# 12. 传递变量到子Make
export UVM_HOME
child:$(MAKE) -C testbench compile# 13. 并行递归
SUBDIRS = rtl dv sw
$(SUBDIRS):$(MAKE) -C $@ all# 14. 条件递归
ifdef RUN_SUBSYS$(MAKE) -C subsystem_tb run
endif

文件操作

# 15. 创建目录
$(SIM_DIR):@mkdir -p $@# 16. 生成文件列表
filelist.f: $(wildcard rtl/*.sv)@echo "// Auto-generated" > $@@find rtl -name "*.sv" >> $@# 17. 批量文件转换
SVFILES = $(patsubst %.v,%.sv,$(wildcard *.v))# 18. 文件存在性检查
ifeq ($(wildcard config.mk),)$(error config.mk not found!)
endif

函数使用

# 19. shell函数
GIT_HASH = $(shell git rev-parse --short HEAD)# 20. subst函数
NEW_PATH = $(subst /old/,/new/,$(PATH))# 21. filter函数
SV_ONLY = $(filter %.sv,$(ALL_FILES))# 22. foreach函数
TESTS = test1 test2 test3
RUN_ALL = $(foreach test,$(TESTS),run_$(test))# 23. call函数
define compile_blockvlog -work $(1) $(2)
endef
$(call compile_block,work_lib,rtl/*.sv)

条件判断

# 24. ifeq条件
ifeq ($(SIMULATOR),vcs)SIM_OPTS = -debug_all
elseSIM_OPTS = -gui
endif# 25. ifdef条件
ifdef COVERAGEVLOG_OPTS += -cm line+cond+fsm+branch
endif# 26. 多条件判断
ifneq ($(SIMULATOR),)
ifneq ($(TEST),)RUN_CMD = ./run_sim.sh
endif
endif

高级模式规则

# 27. 双后缀规则
.sv.o:sv2c $< -o $@# 28. 静态模式规则
OBJS = foo.o bar.o
$(OBJS): %.o: %.cgcc -c $< -o $@# 29. 次要扩展
.SECONDEXPANSION:
$(TESTS): test_%: $$(wildcard %_*.sv)compile_test $@

特殊变量

# 30. 自动变量
%.log: %.test@echo "Running $<"./$< > $@@echo "Output saved to $@"# 31. 目标相关变量
debug: CFLAGS += -g
debug: all# 32. 模式特定变量
%.tb.sv: VLOG_OPTS += +define+TESTBENCH

Include和依赖生成

# 33. include指令
-include config.mk# 34. 自动依赖生成
%.d: %.sv@vlog -M -Mp $@ $<# 35. sinclude(静默include)
sinclude $(DEPS)

实用技巧

# 36. 时间戳
TIMESTAMP = $(shell date +%Y%m%d_%H%M%S)
LOG_FILE = sim_$(TIMESTAMP).log# 37. 检查工具存在
VLOG := $(shell which vlog)
ifeq ($(VLOG),)$(error vlog not found in PATH)
endif# 38. 多级目录创建
DIRS = $(SIM_DIR)/logs $(SIM_DIR)/waves $(SIM_DIR)/coverage
$(DIRS):@mkdir -p $@# 39. 参数化编译
compile_%:vlog +define+CONFIG_$* rtl/config_$*.sv

UVM特定应用

# 40. UVM测试运行
run_%: compile./simv +UVM_TESTNAME=$*_test \+UVM_VERBOSITY=UVM_MEDIUM# 41. 覆盖率合并
merge_cov:urg -dir sim/*.vdb -report coverage.html# 42. 波形控制
ifdef DUMP_WAVESIM_OPTS += +DUMP_WAVE=$(WAVE_FORMAT)
endif# 43. 种子管理
SEED ?= $(shell echo $$RANDOM)
run: ./simv +ntb_random_seed=$(SEED)

错误处理

# 44. 忽略错误
clean:-rm -rf $(SIM_DIR)/*# 45. 错误检查
check_env:@test -n "$(UVM_HOME)" || \(echo "Error: UVM_HOME not set" && exit 1)

并行和性能

# 46. 并行执行
.PARALLEL: $(TESTS)
all: $(TESTS)# 47. 作业服务器
.NOTPARALLEL: regression

调试和输出

# 48. 静默规则
.SILENT: clean# 49. 调试打印
debug_vars:$(info TOP_DIR = $(TOP_DIR))$(info SIMULATOR = $(SIMULATOR))$(warning This is a warning)# 50. 完整示例:多级Makefile系统
# 顶层Makefile
BLOCKS = cpu dma pcie
.PHONY: all $(BLOCKS)
all: $(BLOCKS)@echo "All blocks compiled"$(BLOCKS):@echo "========== Building $@ =========="$(MAKE) -C blocks/$@ all TOP=$(TOP_DIR)regression: all@for test in $(TESTS); do \$(MAKE) run_$$test || exit 1; \doneclean:@for dir in $(BLOCKS); do \$(MAKE) -C blocks/$$dir clean; \done

       这些例子涵盖了UVM SoC验证中常用的Makefile技巧,包括递归构建、自动依赖、条件编译、并行执行等关键功能。

       如何使用Makefile实现UVM测试用例的批量运行和结果收集?能否提供一个更复杂的Makefile例子,包含多个子模块和条件编译?

       可以通过在顶层 Makefile 中定义一组 Testcase、循环运行每个 testcase,并把日志分目录保存,最后 grep 出 PASS/FAIL,再汇总成 CSV 报表。下面给出一个较复杂的示例,涵盖:

  • 多个子模块(blocks/cpu, blocks/dma, blocks/pcie)的递归 build
  • 条件编译开关(COVERAGE、WAVE)
  • test 批量运行(pattern rule +run_%)
  • 日志分目录管理
  • PASS/FAIL 收集并生成 CSV 报表
# Top-level Makefile for UVM SoC Verification
# Usage:
#   make            # build + run all tests + report
#   make COVERAGE=1 # enable coverage
#   make WAVE=1     # enable waveform dump
#   make clean#—— 1. 配置与变量 ——#
SIM_CMD     ?= vcs
SIM_FLAGS   ?= -full64 -quiet
ifeq ($(COVERAGE),1)
SIM_FLAGS   += -cm line+cond+fsm+branch
endif
ifeq ($(WAVE),1)
SIM_FLAGS   += +vpd
endif# 子模块列表(递归 build)
BLOCKS      := cpu dma pcie# 要跑的 UVM 测试用例
TESTS       := basic smoke stress# 日志与结果目录
LOG_DIR     := logs
PASS_LOG    := $(LOG_DIR)/pass.log
FAIL_LOG    := $(LOG_DIR)/fail.log
RESULT_CSV  := $(LOG_DIR)/results.csv#—— 2. 伪目标定义 ——#
.PHONY: all build run_tests report clean help $(BLOCKS) $(addprefix run_,$(TESTS))
.DEFAULT_GOAL := all#—— 3. 默认流程 ——#
all: build run_tests report#—— 4. 子模块递归 build ——#
build: $(BLOCKS)
$(BLOCKS):@echo "[BUILD] block=$@"$(MAKE) -C blocks/$@ build#—— 5. 批量运行测试 ——#
run_tests: clean-logs $(addprefix run_,$(TESTS))clean-logs:@rm -rf $(LOG_DIR)@mkdir -p $(LOG_DIR)@> $(PASS_LOG) > $(FAIL_LOG)# pattern rule: run_<test>
run_%:  ## Run UVM test $*@echo "[RUN ] test=$*"@mkdir -p $(LOG_DIR)/$*@$(SIM_CMD) $(SIM_FLAGS) \-o simv_$* +UVM_TESTNAME=$* +UVM_VERBOSITY=UVM_MEDIUM \2>&1 | tee $(LOG_DIR)/$*/run.log || true@grep -E "UVM_FATAL|UVM_ERROR" $(LOG_DIR)/$*/run.log \&& echo "$*:FAIL" >> $(FAIL_LOG) \|| echo "$*:PASS" >> $(PASS_LOG)#—— 6. 生成汇总报表 ——#
report: run_tests@echo "test,result" > $(RESULT_CSV)@sed 's/:PASS/,PASS/' $(PASS_LOG) >> $(RESULT_CSV)@sed 's/:FAIL/,FAIL/' $(FAIL_LOG) >> $(RESULT_CSV)@echo "[REPORT] Generated: $(RESULT_CSV)"#—— 7. 清理 ——#
clean:@echo "[CLEAN] all"@rm -rf simv_* $(LOG_DIR)@for d in $(BLOCKS); do \$(MAKE) -C blocks/$$d clean; \done#—— 8. 帮助信息 ——#
help:@echo "Usage:"@echo "  make [COVERAGE=1] [WAVE=1]        # build, run all tests, gen report"@echo "  make run_<testname>               # run single test"@echo "  make clean                        # clean all artifacts"

说明:

  1. 通过 SIM_FLAGS 的条件追加实现覆盖率和波形开关。
  2. build 目标依赖 $(BLOCKS),对每个子目录递归调用子 Makefile。
  3. run_% 模式规则批量跑 basicsmokestress,日志分别保存在 logs/basic/run.log 等目录下。
  4. grep 日志中 UVM_FATALUVM_ERROR 来判断失败,并分别写入 pass.log / fail.log
  5. report 目标将结果拼成一个标准 CSV (test,result) 方便后续自动化处理或 Jenkins 报告。

这个示例可以根据项目需求扩展更多子模块、更多测试、或加入并行执行(.PARALLEL:)等特性。

http://www.xdnf.cn/news/14435.html

相关文章:

  • 三维重建 —— 5. 双目立体视觉
  • CNN中的感受野
  • linux 常用工具的静态编译之一
  • Python打卡训练营-Day31-文件的规范拆分和写法
  • Vue2 与 Vue3 中环境变量配置的差异详解。
  • 电力系统时间同步检测技术
  • (下)通用智能体与机器人Transformer:Gato和RT-1技术解析及与LLM Transformer的异同
  • 【Golang面试题】什么是 sync.Once
  • 安全生产台账系统
  • 【无标题】二维势能塌陷的拓扑色动力学:数学物理框架与引力本质探索
  • 华为OD机试_2025 B卷_数组排列求和(Python,100分)(附详细解题思路)
  • vim编辑常用命令
  • JAVA理论第十七章-RocketMQKafaka
  • 【Linux教程】Linux 生存指南:掌握常用命令,避开致命误操作
  • 基于可靠消息确保分布式事务的最终一致性:以电商系统中订单服务的新建订单为例
  • C# 使用 TreeView 实践 WinRiver II 的测量管理功能
  • 篇章六 论坛系统——业务开发——实现业务功能
  • Java 与 MySQL 性能优化:Linux服务器上MySQL性能指标解读与监控方法
  • 修改Typora快捷键
  • 新的激活函数B-SiLU和NeLU:ReLU函数的复兴
  • 6.14项目一话术
  • 四六级英语作文模版
  • LeetCode 第72题:编辑距离(巧妙的动态规划方法)
  • 同旺科技 USB TO SPI / I2C适配器(专业版)--EEPROM读写——C
  • uni-app项目实战笔记14--给全屏页面添加遮罩层
  • 深度学习中的激活函数:PyTorch中的ReLU及其应用
  • 人工智能学习14-Numpy-数组广播机制
  • AtCoder AT_abc410_e [ABC410E] Battles in a Row 题解
  • 如何识别并管理多项目环境下的潜在风险
  • 【Git】使用 SSH 协议 解决 Git 推送失败问题