三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

告别命令行恐惧:用VCS+Verdi在Linux下仿真一个计数器(附完整Makefile)

告别命令行恐惧:用VCS+Verdi在Linux下仿真一个计数器(附完整Makefile)

数字验证新手指南:VCS+Verdi计数器仿真全流程解析

第一次接触数字验证工具链时,面对命令行和复杂的参数选项,很多工程师都会感到无从下手。本文将手把手带你完成一个简单计数器模块的完整仿真流程,从代码编写到波形查看,每个步骤都会详细解释其背后的原理和操作逻辑。

1. 环境准备与工具理解

在开始之前,我们需要明确几个关键工具的作用和关系。VCS是Synopsys公司推出的高性能仿真器,负责将我们的设计代码编译成可执行的仿真程序。Verdi则是强大的调试工具,用于查看和分析仿真产生的波形数据。

对于Linux环境下的数字验证工作,建议使用以下工具组合:

  • 代码编辑器:Vim/VSCode(带SystemVerilog插件)
  • 仿真工具:VCS(编译和运行仿真)
  • 调试工具:Verdi(波形查看和分析)

安装完成后,可以通过以下命令检查工具是否可用:

which vcs which verdi

2. 项目文件结构与代码编写

我们先创建一个清晰的项目目录结构:

counter_project/ ├── rtl/ # 存放设计代码 │ └── counter.v ├── tb/ # 存放测试平台 │ └── tb.sv ├── Makefile # 自动化脚本 └── waves/ # 波形文件存放目录

计数器设计代码(counter.v)实现了一个8位宽的同步计数器:

module counter( input clk, input rst, output reg [7:0] count ); always @(posedge clk or negedge rst) begin if(!rst) count <= 0; else count <= count + 1; end endmodule

测试平台(tb.sv)则负责生成时钟和复位信号,并实例化被测设计:

module tb; reg clk, rst_n; wire [7:0] count; counter dut( .clk(clk), .rst(rst_n), .count(count) ); // 时钟生成 always #5 clk = ~clk; initial begin clk <= 0; rst_n <= 0; #20; rst_n <= 1; #500; $display("Simulation finished."); $finish; end // FSDB波形记录 `ifdef FSDB initial begin $fsdbDumpfile("waves/tb.fsdb"); $fsdbDumpvars; end `endif endmodule

3. 编译与仿真详细解析

使用VCS编译时,各个参数都有其特定作用:

参数说明必要性
-full64使用64位模式必需
-sverilog支持SystemVerilog语法必需
-debug_access+all启用调试功能可选但推荐
-lca -kdb支持Verdi知识数据库需要Verdi时必需
-fsdb支持FSDB波形格式需要波形时必需
+define+FSDB定义FSDB宏配合测试平台使用

完整的编译命令如下:

vcs -full64 -sverilog -debug_access+all -lca -kdb -fsdb +define+FSDB rtl/counter.v tb/tb.sv

编译成功后,会生成simv可执行文件。运行仿真有两种方式:

  1. 纯命令行模式:./simv
  2. 带Verdi图形界面:./simv -gui=verdi

4. Verdi波形调试实战

仿真完成后,我们可以使用Verdi查看波形。如果采用非GUI模式仿真,需要手动打开波形文件:

verdi waves/tb.fsdb

Verdi界面中几个关键操作:

  1. 信号获取:点击工具栏"Get Signals"按钮
  2. 波形添加:在信号列表中选择信号,点击"Add to Wave"
  3. 时间控制
    • run 100:运行100个时间单位
    • run -all:运行到仿真结束
  4. 调试技巧
    • 使用"Markers"标记关键时间点
    • 通过"Signal Value"窗口实时监控信号值

5. 自动化Makefile实现

为了简化重复操作,我们可以编写Makefile来自动化整个流程:

# 文件配置 RTL_SOURCES = rtl/counter.v TB_SOURCES = tb/tb.sv # 工具选项 VCS_OPTS = -full64 -sverilog -debug_access+all -lca -kdb -fsdb +define+FSDB # 默认目标 all: comp run # 编译目标 comp: vcs $(VCS_OPTS) $(RTL_SOURCES) $(TB_SOURCES) # 运行仿真(命令行) run: ./simv # 运行仿真(带Verdi GUI) rung: ./simv -gui=verdi # 直接打开波形 verdi: verdi waves/tb.fsdb # 清理生成文件 clean: rm -rf csrc simv simv.daidir waves/*.fsdb novas.* ucli.key rm -rf *.log *.vpd urgReport verdiLog

使用这个Makefile,我们可以通过简单命令完成整个流程:

  • make comp:编译设计
  • make run:运行仿真(命令行)
  • make rung:运行仿真(带Verdi界面)
  • make verdi:打开已有波形文件
  • make clean:清理生成文件

6. 常见问题与调试技巧

在实际操作中,新手常会遇到一些问题:

  1. 编译错误

    • 检查文件路径是否正确
    • 确认SystemVerilog语法是否正确
    • 查看错误信息中的行号定位问题
  2. 波形文件未生成

    • 确保编译时加入了-fsdb +define+FSDB选项
    • 检查测试平台中是否包含FSDB相关代码
  3. Verdi无法显示信号

    • 确认仿真已经运行了一段时间(信号需要有变化才会显示)
    • 检查是否在正确的时间段添加了信号

调试时可以尝试以下命令查看仿真信息:

./simv -l sim.log # 将仿真日志输出到文件

对于更复杂的调试,可以在Verdi中使用以下高级功能:

  • 信号追踪:追踪信号驱动和负载
  • 状态机查看:可视化状态机转换
  • 代码覆盖率:分析测试覆盖率
← 返回列表