Linux基础与Shell脚本:验证工程师的生存工具

说实话,我见过不少刚入行的验证工程师,拿着Windows那套思维来搞Linux环境,结果第一天就卡在文件查找上。嗯,这很正常。但如果你想在验证这行走得远,Linux和Shell脚本就是你的左右手。

我个人习惯把Linux命令分成三类:查找类、文本处理类、环境配置类。今天咱们就把这三块啃透。

核心观点:验证工程师80%的日常操作,都可以用grep、find、sed、awk这四把刀解决。剩下的20%,靠环境变量和脚本自动化。

2.1 四把刀:grep、find、sed、awk

2.1.1 grep —— 日志里的探照灯

grep这玩意儿,说白了就是在一堆文本里找匹配的行。我在项目中遇到过最典型的场景:仿真跑了三天三夜,日志文件几个G,要找出所有"Error"和"Warning"。

# 基本用法
grep "Error" sim.log

# 递归搜索整个项目
grep -r "FATAL" ./project/

# 显示匹配行前后各5行上下文
grep -n -C 5 "TIMEOUT" sim.log

# 用正则匹配多种错误类型
grep -E "Error|Fatal|Assertion" sim.log

我的小技巧:调试时我习惯用 grep -n 显示行号,配合vim直接跳转。另外,grep -v 可以排除干扰行,比如过滤掉时间戳。

2.1.2 find —— 文件系统的GPS

你想想看,一个验证项目动辄几十万文件,要找某个testbench或者某个配置文件,靠肉眼翻?不现实。

# 按名字找文件
find . -name "*.sv"

# 按类型找目录
find . -type d -name "test_*"

# 按修改时间找(最近7天改过的)
find . -mtime -7 -name "*.log"

# 找到后直接执行操作(比如删除)
find . -name "*.bak" -exec rm {} \;

我曾经有一次,为了定位一个诡异的仿真崩溃,用 find . -mmin -5 找到了刚刚被修改的配置文件,发现是同事误改了参数。嗯,find 救了我一命。

2.1.3 sed —— 流式文本手术刀

sed 不需要打开文件就能做替换、删除、插入。我最常用的场景是批量修改编译脚本里的路径。

# 替换所有文件中的旧路径为新路径
sed -i 's|/old/path|/new/path|g' compile.sh

# 删除空行
sed -i '/^$/d' filelist.f

# 在第10行后插入一行
sed -i '10a\new_include_path' filelist.f

注意:-i 参数直接修改原文件,建议先不加 -i 跑一遍看看结果,确认无误再加。我曾经手滑把整个脚本改废过……

2.1.4 awk —— 列处理神器

awk 擅长处理结构化文本,比如日志里按空格或逗号分隔的字段。我个人习惯用它来提取仿真报告里的关键数据。

# 打印第1列和第3列
awk '{print $1, $3}' report.txt

# 按逗号分隔,打印第2列
awk -F',' '{print $2}' coverage.csv

# 条件过滤:只打印覆盖率低于90%的行
awk '$2 < 90 {print $1, $2}' coverage.txt

2.2 环境变量:PATH 和 LD_LIBRARY_PATH

环境变量这东西,说白了就是给系统指路用的。你敲一个命令,系统去PATH里找;你跑一个仿真,动态链接库去LD_LIBRARY_PATH里找。

环境变量 作用 验证场景
PATH 可执行文件的搜索路径 让系统找到vcs、verdi、make等工具
LD_LIBRARY_PATH 动态链接库的搜索路径 让仿真器找到DPI库、VIP库
HOME 用户主目录 脚本中引用路径的基准
# 查看当前PATH
echo $PATH

# 临时添加路径(仅当前shell有效)
export PATH=/tools/synopsys/vcs/bin:$PATH

# 永久添加(写入.bashrc或.cshrc)
echo 'export PATH=$PATH:/tools/cadence/incisive/bin' >> ~/.bashrc
source ~/.bashrc

避坑指南:我曾经把LD_LIBRARY_PATH设错了顺序,导致仿真器加载了旧版本的库,跑出来的结果全是错的。排查了两天才发现。建议:把最常用的工具路径放在最前面,系统会按顺序查找。

2.3 编写第一个自动化编译脚本

好了,理论讲完了,咱们来点实战。下面这个脚本是我个人习惯的模板,用来一键完成RTL编译和仿真。

#!/bin/bash
# ============================================
# 自动化编译脚本 - compile.sh
# 用途:一键编译RTL并启动仿真
# 作者:你的名字
# ============================================

# 1. 设置环境变量
export VCS_HOME=/tools/synopsys/vcs
export VERDI_HOME=/tools/synopsys/verdi
export PATH=$VCS_HOME/bin:$VERDI_HOME/bin:$PATH

# 2. 定义变量
PROJECT_DIR=$(pwd)
RTL_DIR="$PROJECT_DIR/rtl"
TB_DIR="$PROJECT_DIR/tb"
WORK_DIR="$PROJECT_DIR/work"
LOG_DIR="$PROJECT_DIR/logs"

# 3. 创建目录
mkdir -p $WORK_DIR $LOG_DIR

# 4. 收集文件列表
RTL_FILES=$(find $RTL_DIR -name "*.sv" -o -name "*.v")
TB_FILES=$(find $TB_DIR -name "*.sv")

# 5. 执行编译
echo "开始编译..."
vcs -full64 \
    -sverilog \
    -debug_access+all \
    -l $LOG_DIR/compile.log \
    $RTL_FILES $TB_FILES \
    -o $WORK_DIR/simv

# 6. 检查编译结果
if [ $? -eq 0 ]; then
    echo "编译成功!"
    echo "运行仿真:$WORK_DIR/simv"
else
    echo "编译失败,请检查 $LOG_DIR/compile.log"
    exit 1
fi

脚本编写要点:

  • 开头加 #!/bin/bash 指定解释器
  • 用 set -e 让脚本在遇到错误时自动退出
  • 用变量代替硬编码路径,方便移植
  • 检查每条命令的返回值 $?

2.4 本章知识体系

下面这张图把本章的核心知识点串起来了。你可以把它当作一张速查地图。

Linux基础与Shell脚本知识体系 Linux基础与Shell脚本知识体系 Linux命令四把刀 grep find sed awk 环境变量配置 PATH LD_LIBRARY_PATH HOME 自动化编译脚本 变量定义 文件收集 编译执行 错误检查 三大模块相互配合:命令是工具,环境变量是路径,脚本是自动化流水线

2.5 本章小结

这一章的内容,说白了就是验证工程师的"生存三件套":

  • 四把刀:grep找内容、find找文件、sed改文本、awk提数据
  • 两条路:PATH让系统找到工具,LD_LIBRARY_PATH让工具找到库
  • 一个脚本:把重复劳动自动化,把精力留给真正的问题

我个人建议,别急着背命令参数。先动手把上面的脚本跑起来,遇到不会的再查。用着用着,你就发现这些命令已经长在手里了。