SystemVerilog小白入门1, iverilog+VScode
芯片验证领域主流语言是SystemVerilog。作为 “超级集合” 语言,SystemVerilog 几乎涵盖了芯片验证的所有需求:
- OOP 特性:通过类(Class)、继承、多态等构建可重用的验证组件(如 UVM 库)。
- 约束随机激励:自动生成海量测试用例,覆盖边界场景(如 rand、constraint 关键字)。
- 功能覆盖率:通过 covergroup 统计测试覆盖度,确保验证充分性。
- 断言(SVA):实时监控设计行为是否符合规格,快速定位功能错误。
- 是 UVM(通用验证方法学)的唯一支持语言,也是业界主流验证框架的基础。
如果说Verilog像C语言,那SystemVerilog就是C++。我大概看了SytemVerilog的数据类型:逻辑类型、双状态数据类型、定宽数组、合并数组、动态数组、队列、关联数组……我滴妈,把我这个资深程序猿看蒙圈了,这是C中有C++,C++中有Python。光看书肯定不行,得上手实操。
开发SystemVerilog的典型环境有QuestaSim、VCS等,功能强大,价格美丽,下载安装比较费劲。那个人学习SystemVerilog有没有简单免费又好用的工具呢?你猜的没错,它来了!
下面隆重介绍免费三人组:
Icarus Verilog + GTKWave + VS Code
- Icarus Verilog(即iverilog):开源 SystemVerilog 编译器,支持部分 SV 特性(如基本类、约束随机,不支持 UVM 全部功能)。
- GTKWave:开源波形查看器,用于分析仿真结果。
- VS Code:搭配插件实现代码编辑和语法检查。
优势:完全免费,适合学生和初学者学习 SystemVerilog 基础语法(如模块设计、简单测试用例)。
局限:对 UVM 和复杂 SVA 支持有限,不适合工业级验证。
废话不多说,下面进入实操环节。
一、安装iverilog(包含GTKWave)
- 下载安装iverilog(原则:必须accept,能选尽选)
下载地址:https://bleyer.org/icarus/
提示:这里勾选“Install GTKWave”,就可以顺便安装GTKWave了。
提示:这里勾选“Add executable folder(s) to the user PATH”,否则安装后需要手动添加PATH。
安装完成后,桌面会出现一个图标 ,是不是很常见?是不是得双击?
然后你就发现上当了,居然打开了安装文件夹!
是不是一脸蒙?软件界面呢?好吧,它就没有软件界面。
将这个吴用的图标删了吧,省的手痒。
打开命令行界面会不会?(不会?按Win+R,执行cmd)
执行:iverilog
如果出现下面的提示内容,那就是安装成功了。
二、安装VScode
安装过程就不详述了,可以参考我的其他文章。
VScode需要安装下面4个插件。
三、Verilog编程
1、新建一个文件夹用于存放代码文件。
2、在VScode中打开该文件夹。
文件->打开文件夹
3、新建一个sv文件。
输入代码:
`timescale 1ns/1nsmodule test1();
reg a;
reg b;initial begin$dumpfile("wave1.vcd");$dumpvars(0,test1);
endinitial begina=0;b=0;#100$display("Hello World!");a=0;b=1;#100a=1;b=0;#100$finish();
endendmodule
代码解释:
$dumpfile(“wave1.vcd”);是为了将波形数据保存到wave1.vcd中,之后便于使用GTKwave工具查看波形。
$dumpvars(0,test1);是为了设置需要记录的信号,test1就是当前模块的名称,0指的是记录该模块下所有信号(包括调用的模块下的信号)的波形,并保存到.vcd文件中。
四、编译仿真
1、在VScode中打开命令行终端。
2、编译代码
在终端中执行命令:
iverilog -o test1 test1.sv
解释:test1.sv是需编译的代码文件;test1是编译输出的文件。
如果没有提示任何信息,就代表编译成功。
3、仿真
在终端中执行命令:
vvp test1
从提示信息可以看出:
wave1.vcd已经生成;
输出Hello World!
4、查看波形
在终端中执行命令:
gtkwave wave1.vcd
将弹出GTKWave窗口
点“test1”,然后点“reg a”、“reg b”,最后点“Insert”。在右侧就可以看到a和b的波形了。
五、SystemVerilog编程
上述的代码用的是Verilog的语法,下面试一试systemverilog的一些新特性。
1、动态数组
修改test1.sv的内容为:
module test1();int dyn1[],dyn2[];initial begindyn1=new[10];foreach(dyn1[j]) dyn1[j]=j;dyn2=new[5](dyn1);$display("dyn1:%d %d %d %d %d", dyn1[0],dyn1[1],dyn1[2],dyn1[3],dyn1[4]);$display("dyn2:%d %d %d %d %d", dyn2[0],dyn2[1],dyn2[2],dyn2[3],dyn2[4]);dyn1.delete();dyn2.delete();
endendmodule
在终端中执行命令:
iverilog -g2012 -o test1 test1.sv
vvp test1
注意:与编译Verilog相比,这里要添加-g2012!
代码解释:使用new[10]给dyn1分配了10个int空间,使用foreach给dyn1赋值;使用new[5](dyn1)给dyn2分配了5个int空间,并赋值为dyn1的前5个值。
2、队列
修改test1.sv的内容为:
module test1();
int ivalue1;
int que1[$]={0,20,30,40,50};
initial beginque1.insert(1,10);//在位置1插入10$display("-----------------");foreach(que1[i]) $display(que1[i]);que1.delete(5); //删除第5个(即50)$display("-----------------");foreach(que1[i]) $display(que1[i]);que1.push_back(60); //在队尾追加一个数$display("-----------------");foreach(que1[i]) $display(que1[i]);ivalue1 = que1.pop_back();//队尾出队一个数$display("-----------------");$display(ivalue1);
end
endmodule
执行结果: