基于 VSCode + Icarus 的 Verilog 编译和仿真

文章目录

前言

​ 我校计算机组成原理课程的实验会用到 Verilog 语言,学校建议使用 Modelsim 软件作为实验工具。但是在实践中我们发现,Modelsim 占用空间大,UI不太友好,且难以上手。一个更重要的原因是,除非是电子信息工程专业,或者打算将来从事计算机底层研究的,很多人通过这门课之后,未来很长一段时间不会再使用这一工具,不值得对一个完全陌生的新工具花费大量学习成本,部分人希望能在 Visual Studio Code 中集成 Verilog 支持,实现一个相对轻量化的 Verilog 编译和仿真环境。

​ 本教程基于 Windows 平台(x64),工具下载链接均可在国内网络环境下访问。**如果你不了解本教程提到的一些工具,请不要轻易跳过某些步骤,这些很可能是未知错误和危险的根源。因过度自信而不遵照本教程所造成的损害,教程制作者概不负责。**作为一个教程,我无法直接再分发本教程中使用到的安装包等工具,因为它们通常具有商业许可证,不允许公开再分发。但我可以提供下载链接,你可以点击链接前往官网下载,或联系学校请求内部分发(如果有)。

准备

  1. Visual Studio Code(代码编辑器,以下简称VSCode
  2. Digital IDE(VSCode的一个扩展,以下简称DIDE
  3. Icarus Verilog(编译和仿真工具,以下简称iVerilog
  4. GTKWave(信号波形图渲染工具,以下简称gwave

值得注意的是,Digital IDE 它不仅支持 iVerilog,它还支持更高级的软件如 Vivado,Modelsim 等,我们的初衷是构建一个轻量化的 iVerilog 环境,所以我们当然是不会使用其他工具的。不过,如果你仅仅是不满 Modelsim 的 UI 和操作,但承认 Modelsim 的仿真实力的话,你确实可以尝试使用 VSCode + DIDE + Modelsim 的组合。本教程不涉及它们,但是让 DIDE 调用 Modelsim ,和 DIDE 调用 iVerilog 的配置方法是差不多的,你可以参考。

安装 Visual Studio Code

(已经完成的可以直接跳转到安装DIDE(#安装 Digital IDE 扩展))

  1. 前往官网下载 VSCode 安装包。
    VSCode 官网下载
  2. 打开安装包,依照提示安装 VSCode。

安装 Icarus Verilog

  1. 前往官网,下载最新版 iVerilog 安装包。

    Icarus Verilog for Windows

  2. 运行安装包,指定安装路径。

    请注意,不要把 iVerilog 安装在含有空格的目录下,否则 DIDE 扩展将无法调用 iVerilog !

  3. 在安装组件的页面,确保你选择了 "Full Installation",保证依赖环境和 gwave 都装上。

  4. 最后一个要强调的是,强烈建议勾选 Add executable folder(s) to the user PATH ,即将可执行文件所在文件夹加入到用户 PATH 环境变量,这使得你可以在终端(命令行)的任何路径下都可以直接调用 iverilog 和 gtkwave 这两个命令。虽然实际使用中你不需要亲自调用它们,但是 DIDE,它需要调用 iverilog 和 gtkwave 这两个命令,如果你这步照着做了,在配置 DIDE 扩展的时候你将获得极大的便利。

安装 Digital IDE 扩展

  1. 打开 Visual Studio Code,在左边栏找到"扩展"
  2. 搜索 Digital IDE 并安装,作者为sterben

配置 Digital IDE 扩展

  1. 找到 DIDE 扩展,点击齿轮,进入该扩展的设置
  2. 如果你完整地执行了前述安装注意事项,你只需要做一个最小更改,找到 Digital-ide › Function › Lsp › Linter › Verilog: Diagnostor 设置项,点击下拉菜单将其设置为 iverilog
  3. 至此,DIDE 扩展也配置好了。

在代码中建立信号转储

​ 安装完成工具不等于我们就能够对 Verilog 程序进行波形仿真,我们需要在代码中将我们的各个元件的信号转储出去,让它们能够被工具所发现,我们的工具才能够制作波形图。

​ 我们观察以下示例代码:

verilog 复制代码
// adder1
module adder1(
    input  a,
    input  b,
    input  cin,
    output sum,
    output cout
);

    assign sum  = a ^ b ^ cin;
    assign cout = (a & b) | (b & cin) | (a & cin);

endmodule

// tb_adder1
module tb_adder1;

    reg  a;
    reg  b;
    reg  cin;
    wire sum;
    wire cout;

    adder1 uut (
        .a(a),
        .b(b),
        .cin(cin),
        .sum(sum),
        .cout(cout)
    );

    initial begin
        $dumpfile("tb_adder1.vcd");		// 定义转储文件名
        $dumpvars(0, tb_adder1);		// 选择转储信号来源
        a = 0; b = 0; cin = 0; #10;
        a = 0; b = 0; cin = 1; #10;
        a = 0; b = 1; cin = 0; #10;
        a = 0; b = 1; cin = 1; #10;
        a = 1; b = 0; cin = 0; #10;
        a = 1; b = 0; cin = 1; #10;
        a = 1; b = 1; cin = 0; #10;
        a = 1; b = 1; cin = 1; #10;
        $finish;						// 结束仿真信号转储
    end

endmodule 

​ 以上是 1 位全加器及其测试模块(testbench),1 位全加器非常简单,我们重点观察 testbench 中的 initial 块:

verilog 复制代码
initial begin
    
    $dumpfile("tb_adder1.vcd");		// 定义转储文件名
    $dumpvars(0, tb_adder1);		// 选择转储信号来源
    a = 0; b = 0; cin = 0; #10;
    a = 0; b = 0; cin = 1; #10;
    a = 0; b = 1; cin = 0; #10;
    a = 0; b = 1; cin = 1; #10;
    a = 1; b = 0; cin = 0; #10;
    a = 1; b = 0; cin = 1; #10;
    a = 1; b = 1; cin = 0; #10;
    a = 1; b = 1; cin = 1; #10;
    $finish;						// 结束仿真信号转储
    
end

​ initial 块做了什么事情呢?它首先执行了一个系统命令 dumpfile ,它告诉解释器,从现在开始,我计划将信号输出到当前目录下的 tb_adder_1.vcd 的文件中,下一行告诉解释器,我期望解释器记录 tb_adder1 模块中所有声明的信号,通常我们进行波形仿真,我们都是使用 0 作为第一个参数来表示全部信号,第二个参数一般选择顶层模块,我们编写 verilog 的时候习惯将其命名为 top_module 或 tb_xxx,在本例中,我们的信号序列都编写在 tb_adder1 的模块中,所以我们写的就是 tb_adder1。随后每隔 10 个单位时间,a、b 两个加数和外来进位 cin 都会变化,1 位全加器只需要 8 例就能测试完全部功能,结束之后,我们调用系统命令 finish,结束信号转储,保存相应的 vcd 文件。

执行编译和仿真

​ 当你打开一个 verilog 文件时,你或许会注意到有些模块上出现了内联的文字按钮(官方称之为 CodeLens )

​ 我们刚刚的 tb_adder1 代码就是可以直接仿真的,点击 Simulate,你预期看到的画面是:

​ 什么都没有,这是因为,虽然我们将所有信号都转储了,但是 DIDE 允许你只渲染你感兴趣的信号的波形,现在你尚未选择要渲染的波形,那当然什么都没渲染出来。你可以点击右侧的加号,选择顶层模块中的输入和输出,观察是否符合预期。

如果模块是由多个模块构成的,你甚至可以观察内部所有的中间信号的值,看到所有信号变化的过程。如果你认为波形的间隔不符合你的预期,你可以在 verilog 代码的开头中添加一句:

verilog 复制代码
`timescale 1ps/1ps
// 它的含义是设定 1 单位的时间间隔为 1 ps,仿真最小精度为 1 ps

​ 另外我们可以看到,我们的文件夹中出现了一些新的文件,其中 vcd 文件存储了信号波形数据,view 文件则是存储了一些华丽的渲染。

​ 你可以自由探索扩展的其它功能。

常见问题

问题 原因 解决
无法仿真,没有产生相应的 vcd 文件 你的 verilog 代码中没有 $dumpfile 指令 在 initial begin 之后,仿真模拟之前,加上 $dumpfile("<文件名>.vcd");
已经修改过代码,但是波形还是旧的 gtkwave 使用了缓存中的数据,且缓存没有被更新 删除旧的 vcd 和 view 文件重新点击仿真
仿真界面打开了,但是右侧信号栏也没有找到任何东西,没有我想要的信号 你的 verilog 代码中没有 $dumpvars 指令或者有但是漏掉了你想要的信号 确保 $dumpvars 指令的第一个参数为 0,第二个参数为元件的最顶层的模块
直接卡死,毫无输出 你的 verilog 代码中没有 $finish 指令,这会导致仿真一直在进行,且没有停止 在完成所有信号变化结束后,执行 $finish 指令
波形不完整 有些测试用例可能没被写入 vcd 文件 确保你的测试用例包裹在两个 dump 指令和 finish 指令之间
无法编译且终端有个奇怪的前缀和乱码 你大概率把 iVerilog 装在有空格的路径下了 重装iverilog
无法编译,提示 Digital IDE 找不到 iverilog 或 gtkwave 你大概率在安装 iVerilog 时忘记点击 Add to PATH 了 将 gtkwave 和 iVerilog 安装目录下的 bin 目录手动加入环境变量 PATH 或重装一遍
相关推荐
weixin_452077641 小时前
oai compatible provider for copilot for deepseek UI界面设置
vscode·copilot
xiaobobo33302 小时前
vscode如何免秘钥登入Ubuntu
vscode·ssh·免秘钥登入·ubuntu虚拟机
似夜晓星辰2 小时前
Markdown文本编辑器Typora平替
编辑器·github
谷哥的小弟4 小时前
(最新版)VSCode安装图文详解教程
ide·vscode·编辑器·教程·前端开发·图文
xiaoliuliu123454 小时前
LaTeX 2023 (TeX Live + TeXstudio) 安装与汉化教程 Windows版:自定义路径+编辑器配置指南
windows·编辑器
IOT.FIVE.NO.15 小时前
Codex+Vscode+Remote ssh+ 服务器自定义第三方API配置保姆级教程
ide·vscode·编辑器
xiaobobo33305 小时前
vscode打开Ubuntu虚拟机中文件资源管理器加载慢
vscode·ubuntu·资源管理器·加载慢
ai_coder_ai6 小时前
使用web ide开发和调试自动化脚本
前端·ide·自动化
香菇滑稽之谈6 小时前
VSCode配置QT环境
ide·vscode·qt