杰瑞科技汇

Modelsim使用教程,从入门到上手难不难?

ModelSim 使用教程

什么是 ModelSim?

ModelSim 是由 Mentor Graphics(现为 Siemens EDA)开发的一款业界领先的硬件描述语言 仿真器,它支持 VHDL 和 Verilog 两种主流的 HDL 语言,并且支持混合仿真,ModelSim 主要用于:

Modelsim使用教程,从入门到上手难不难?-图1
(图片来源网络,侵删)
  • 功能仿真:在综合之前,验证你的代码逻辑是否正确。
  • 时序仿真:在综合和布局布线之后,加入实际的延迟信息,验证电路在真实硬件环境下的工作情况。

本教程主要讲解功能仿真的基本流程。


环境准备

  1. 安装 ModelSim:确保你已经成功安装了 ModelSim,常见的版本有 ModelSim PE (Personal Edition) 和 SE (Student Edition),本教程的界面和操作在大多数版本中通用。
  2. 选择界面:ModelSim 有两种界面:
    • 图形用户界面:通过点击菜单和按钮进行操作,直观易学,适合初学者。
    • 命令行界面:通过输入命令行指令进行操作,适合脚本化和自动化。

本教程将主要使用 图形用户界面


一个完整的仿真流程:以一个简单的 2-1 MUX 为例

我们将按照以下步骤,使用 ModelSim 对一个 2-1 选择器 进行仿真。

步骤概览:

Modelsim使用教程,从入门到上手难不难?-图2
(图片来源网络,侵删)
  1. 创建项目
  2. 创建设计文件
  3. 编译设计文件
  4. 创建仿真文件
  5. 运行仿真
  6. 分析波形
  7. 调试(高级)
  8. 生成仿真报告

步骤 1:创建新项目

  1. 打开 ModelSim。
  2. 在菜单栏选择 File -> New -> Project...
  3. 弹出 "Create Project" 对话框:
    • Project Name: 输入项目名称,my_mux
    • Project Location: 选择一个你想要保存项目的文件夹。
    • Default Library: 保持默认的 work 库即可。work 库是 ModelSim 的当前工作库,用于存放编译后的结果。
  4. 点击 OK

右侧会出现一个 Project 窗口,里面是空的。

步骤 2:创建设计文件

我们将创建一个 Verilog 模块 mux_2to1.v

  1. 在 Project 窗口中,点击右键,选择 Add file to Project...
  2. 在弹出的对话框中:
    • File name: 输入 mux_2to1.v
    • Add file as Type: 选择 Verilog
  3. 点击 OK

mux_2to1.v 文件已经添加到项目中,双击该文件,在编辑器中输入以下代码:

// mux_2to1.v
// 一个简单的 2-1 选择器
module mux_2to1 (
    output      out,
    input       [1:0] in,    // 输入数据 in[1] 和 in[0]
    input       sel         // 选择信号
);
    // 当 sel 为 0 时,选择 in[0];当 sel 为 1 时,选择 in[1]
    assign out = sel ? in[1] : in[0];
endmodule

保存文件(快捷键 Ctrl + S)。

Modelsim使用教程,从入门到上手难不难?-图3
(图片来源网络,侵删)

步骤 3:编译设计文件

编译的作用是将你的 HDL 代码(如 Verilog)转换成 ModelSim 可以执行的中间格式。

  1. 在 Project 窗口中,右键点击 mux_2to1.v 文件。
  2. 选择 Compile -> Compile

如果编译成功,Project 窗口中的文件图标会变成一个绿色的对勾 ,并且底部的 Transcript 窗口会显示 # ** Compile of mux_2to1.v was successful.**

如果编译失败,Transcript 窗口会显示错误信息,你需要根据错误提示返回编辑器修改代码,然后重新编译。

步骤 4:创建仿真文件(Testbench)

Testbench 是一个没有输入输出的模块,它实例化你的设计模块,并生成激励信号来驱动设计模块,从而观察其输出行为。

  1. 再次在 Project 窗口中右键,选择 Add file to Project...
  2. 文件名输入 tb_mux_2to1.v,类型选择 Verilog,然后点击 OK
  3. 双击 tb_mux_2to1.v 并输入以下代码:
// tb_mux_2to1.v
// 2-1 选择器的测试平台
`timescale 1ns / 1ps // 定义时间尺度:1纳秒为基本时间单位,精度为1皮秒
module tb_mux_2to1();
    // 定义内部信号,用于连接测试平台和 DUT (Design Under Test)
    reg         sel;
    reg  [1:0]  in;
    wire        out;
    // 实例化被测试的模块
    // 将 DUT 的端口与我们定义的内部信号连接起来
    mux_2to1 uut (
        .out (out),
        .in  (in),
        .sel (sel)
    );
    // 生成激励信号的 initial 块
    initial begin
        // 初始化输入
        in  = 2'b00;
        sel = 1'b0;
        // 打印仿真开始信息
        $display("Simulation started at time %0t", $time);
        // 测试场景 1: sel=0, in[1]=0, in[0]=1. 预期 out=1
        #10 in = 2'b01; // 在 10ns 时刻改变 in
        #10;
        // 测试场景 2: sel=1, in[1]=0, in[0]=1. 预期 out=0
        #10 sel = 1'b1;
        #10;
        // 测试场景 3: sel=1, in[1]=1, in[0]=0. 预期 out=1
        #10 in = 2'b10;
        #10;
        // 测试场景 4: sel=0, in[1]=1, in[0]=0. 预期 out=0
        #10 sel = 1'b0;
        #10;
        // 打印仿真结束信息
        $display("Simulation finished at time %0t", $time);
        $finish; // 结束仿真
    end
    // 监控信号变化的 always 块
    // 每当 in, sel, or out 变化时,打印当前时间和信号值
    initial begin
        $monitor("Time = %0t, in = %b, sel = %b, out = %b", $time, in, sel, out);
    end
endmodule

保存文件。

步骤 5:运行仿真

现在我们有了一个设计文件和一个测试文件,我们需要将它们一起加载到仿真器中。

  1. 加载设计

    • 在 Project 窗口中,确保 work 库被展开。
    • 按住 Ctrl 键,同时选中 mux_2to1tb_mux_2to1
    • 右键点击,选择 Simulate -> Simulate
  2. 设置仿真

    • 弹出 "Simulate" 对话框,确保 Design 标签页下,Top-level module in simulationtb_mux_2to1
    • 点击 OK

ModelSim 的界面会发生一些变化:

  • Objects 窗口:显示了 tb_mux_2to1 模块中的所有信号(in, sel, out)。
  • Wave 窗口:一个空的波形图,等待你添加信号。
  • Transcript 窗口:显示仿真器加载成功的信息。
  1. 添加信号到波形窗口

    • Objects 窗口中,找到 in, sel, out 信号。
    • 选中它们,然后右键点击,选择 Add -> Wave -> Signals in Region

    波形窗口中就会出现这些信号的名称。

  2. 运行仿真

    • 在菜单栏选择 Simulate -> Run -> Run -All,或者点击工具栏上的绿色 "运行" 按钮。
    • 你会看到波形窗口中出现了信号的变化波形。
  3. 停止仿真

    • 当仿真运行到 $finish 语句时,它会自动停止,你也可以手动点击工具栏上的红色 "停止" 按钮来停止仿真。

步骤 6:分析波形

这是仿真中最关键的一步,通过观察波形,判断你的设计是否按预期工作。

  • 缩放和平移
    • 使用鼠标滚轮可以缩放波形。
    • 按住 Shift 键并拖动鼠标可以平移波形。
    • 使用工具栏上的放大镜和手形图标也可以进行缩放和平移。
  • 检查信号值
    • 在波形上,光标所在位置的信号值会显示在波形图的顶部。
    • 对比波形和 Testbench 中的 #10 时间点,验证每个测试场景的输出是否符合预期。
      • 10ns20ns 之间,sel=0, in=01out 应该为 1
      • 20ns30ns 之间,sel=1, in=01out 应该为 0
      • ...以此类推。

如果波形正确,恭喜你,你的设计逻辑通过了功能仿真!


步骤 7:调试(高级技巧)

如果仿真结果不正确,你需要进行调试。

  1. 使用断点

    • Source 窗口中,找到你的设计文件 mux_2to1.v
    • 在某一行代码的行号前面点击,会出现一个红色的圆点,这就是一个断点。
    • 运行仿真后,当程序执行到断点处会暂停,你可以检查此时各个信号的值。
  2. 单步执行

    • Transcript 窗口下方的 VSIM 提示符后,可以输入命令进行单步调试。
      • steps:单步执行一条语句。
      • nextn:单步执行,但会跳过过程块(如 initial 块)。
      • run 100:运行 100 个时间单位。
      • restart:重新开始仿真。
  3. 查看信号值

    • Objects 窗口中,右键点击一个信号,选择 Format -> LiteralBinary 等,可以改变其显示格式。
    • Transcript 窗口中,可以直接输入命令查看信号值,print in

步骤 8:生成仿真报告

为了记录和分享仿真结果,可以生成一个包含波形和数据的报告文件。

  1. Wave 窗口中,确保你已经添加了所有需要分析的信号。
  2. 在菜单栏选择 File -> Export -> Image...
  3. 选择你想要的图片格式(如 PNG, JPG),然后保存,这将导出当前波形窗口的截图。
  4. 对于更详细的文本报告,可以在 Transcript 窗口中选择仿真日志,然后复制粘贴到文本文件中。

总结与最佳实践

  • 项目结构:养成良好的项目习惯,将设计文件和测试文件分开存放,并清晰地命名。
  • timescale:在 Testbench 的开头一定要加上 timescale,这关系到你的仿真时间精度。
  • $monitor$display$monitor 会持续监控信号变化并打印,而 $display 只在调用时打印一次。$monitor 在调试时非常有用。
  • 仿真控制:使用 来延迟,$finish 来结束仿真,这是 Testbench 的标准做法。
  • 勤于编译:每次修改代码后,务必重新编译,确保仿真运行的是最新的版本。

通过以上步骤,你已经掌握了 ModelSim 的基本使用流程,这只是冰山一角,ModelSim 还有许多高级功能,如 SystemVerilog 支持、Coverage 分析、与其它工具(如 Quartus, Vivado)的集成等,可以在你熟悉基础后进一步学习。

分享:
扫描分享到社交APP
上一篇
下一篇