记一次使用 iverilog + gtkwave 测试verilog

使用Verilog和GTKwave测试

本文在 windows10raspbianubuntu20.04 上测试通过,其它平台请参考官方文档

iverilog会用到的网址:

  • iverilog 官网:http://iverilog.icarus.com/
  • iverilog windows版本:http://bleyer.org/icarus/
  • iverilog User Guide:http://iverilog.wikia.com/wiki/User_Guide
  • iverilog GitHub:https://github.com/steveicarus/iverilog
  • GTKWave 官网:http://gtkwave.sourceforge.net/
  • GTKWave 手册:http://gtkwave.sourceforge.net/gtkwave.pdf

iverilog使用

使用Verilog编写一个简单的方波产生模块

module testv(
	input sysclk,
	input rst_n,

	output io
);
	
	parameter clk = 50000000;
	parameter io_hz = 100000;
	parameter flip_hz = clk / io_hz / 2;

	reg[31:0] count;
	reg io_o;

	always@(posedge sysclk or negedge rst_n) begin
		if(!rst_n)	count <= 32'd0;
		else begin
			if(count == flip_hz)	count <= 32'd0;
			else	count <= count + 1'b1;
		end 
	end

	always@(posedge sysclk or negedge rst_n) begin
		if(!rst_n)	io_o <= 1'b0;
		else begin
			if(count == 32'd0)	io_o <= ~io_o;
			else	io_o <= io_o;
		end
	end

	assign io = io_o;

endmodule

编写testbench

module testv_tb();

	reg count_clk;
	reg rst;

	wire io_tb;
	wire clk_tb;
	wire rstn_tb;

	initial begin
		count_clk = 1'b0;
		rst = 1'b0;
		#10 count_clk = 1'b1;
		#10 rst = 1'b1;
		#10
		repeat(10000)
			#1 count_clk = ~count_clk;
	end

	/* 什么意思 */
	initial begin
		$dumpfile("testv.lxt");
		$dumpvars(0,testv_tb);
	end


	//always #1 count_clk = ~count_clk;

	assign clk_tb = count_clk;
	assign rstn_tb = rst;

	testv test(clk_tb,rstn_tb,io_tb);
endmodule
  • 通过$dumpfile指定要保存仿真波形数据需要存储到的文件,指定保存在当前目录中testv.lxt文件中(GTKWave还支持LXT,LXT2,VZT,FST和GHW等类型文件)
  • 通过$dumpvars指定要保存仿真波形数据的信号,这里指定为hello_world_tb模块(即本模块)之下及其子模块中的所有信号,当然这个例子中没有子模块,所以仿真数据被存储的为本模块中仅有的两个信号:clkrst_n
  • 结束仿真这里要注意最好用$finish而不是$stop,因为若使用$stop在iverilog仿真完后需要手动停止,而用$finish则会自动停止
  • 使用vvp工具的-n选项可以自动加入$finish$stop

之后就是仿真命令的问题,可使用以下批处理使用iverilog执行仿真并最后使用GTKWave打开仿真波形(将以下代码保存为xxx.bat或.cmd后缀的文件并放入以上verilog相同目录即可)

编译verilog

@echo off
iverilog 	-o	
vvp -m  -lxt
gtkwave <*.vcd>

GTKWave使用

通过上面批处理最后一条中gtkwave命令即可打开GTKWave软件,同时打开了对应的.gtkw或.vcd文件;首次运行打开的为.vcd文件,此时可以看到GTKWave软件界面的Signals和Waves窗口并没有信号显示,需要:

  • 在左上角的SST窗口选中一个模块,此时在其下面窗口就可以看到对应模块的所有信号
  • 在显示信号的窗口选中要查看的信号(ctrl+a全选,ctrl和shift可多选),然后点击其下面的Append按钮即可将这些信号显示到Signals和Waves窗口
  • 在Signals窗口选中各信号,然后按G可以将信号分组,推荐将不同模块的信号分为不同的组,这样方便查看
  • 这样操作后若不保存(类似modelsim也需要保存),下次再次打开.vcd文件仍然为初次打开一样Signals和Waves窗口都没有信号,所以此时ctrl+s将其保存,保存文件名推荐为模块名+.gtkw(配合上面的批处理),这样下次上面的批处理发现存在.gtkw文件则直接打开这个.gtkw文件,这样上面添加显示的信号和分组都存在,而波形数据也为最新的仿真数据

**注:**查看.gtkw文件可以发现其保存的内容不包括波形数据而只包括.vcd文件路径和GTKWave的一些设置(如添加的信号和分组等)

iverilog常用选项

直接运行iverilog -helpiverilog则会显示以下帮助信息,显示了iverilog支持的参数

Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile]
                [-g1995|-g2001|-g2005|-g2005-sv|-g2009|-g2012] [-g]
                [-D macro[=defn]] [-I includedir]
                [-M [mode=]depfile] [-m module]
                [-N file] [-o filename] [-p flag=value]
                [-s topmodule] [-t target] [-T min|typ|max]
                [-W class] [-y dir] [-Y suf] source_file(s)

下面简单列举几个常用的参数的简单说明,详细参数列表请查看http://iverilog.wikia.com/wiki/Iverilog_Flags

选项-g

指定使用verilog的版本,推荐使用最新的-g2012基本的SystemVerilog语法都支持(不完全支持),方便使用SV仿真。如上帮助信息显示支持:

  • -g1995
  • -g2001
  • -g2005
  • -g2005
  • -g2009
  • -g2012

还支持:

  • verilog-ams
  • assertions/no-assertions
  • relative-include/no-relative-include
  • specify/no-specify
  • strict-ca-eval/no-strict-ca-eval
  • strict-expr-width/no-scrict-expr-width
  • xtypes/no-xtypes
  • io-range-error/no-io-range-error

选项-o

指定编译后输出文件,若不指定默认为a.out

选项-y

指定库的目录,编译时发现了一个没有定义的模块时会到这个参数指定的目录中查找,此选项在使用Xilinx和Lattice库时会用到

选项-I

指定verilog中``include包含文件的搜索目录,会按-I`出现顺序查找

选项-D

传递一个宏定义,如-DIS_DEF-DIS_DEF=1,则在verilog中就可以用IS_DEF这个宏定义

选项-t

使用-tvhdl可将verilog转换为VHDL,如将上面的例子转换为VHDL:iverilog -tvhdl -o hello_world_tb.vhd hello_world_tb.v

使用库

若要仿真使用了各FPGA公司IP的设计则需要支持对应公司的库,这里简单介绍使用Xilinx和Lattice公司库的方法

Xilinx

vivado

本人安装的为vivado 2015.3,安装在E盘:E:\Xilinx\Vivado\2015.3;则在使用iverilog编译时使用以下命令即可(替换上面例子中iverilog命令那行):

set vivado_dir=E:\Xilinx\Vivado\2015.3\data\verilog\src
set vivado_lib="-y%vivado_dir%" "-y%vivado_dir%\retarget" "-y%vivado_dir%\unifast" "-y%vivado_dir%\unimacro" "-y%vivado_dir%\unisims" "-y%vivado_dir%\xeclib"

iverilog -g2012 -o "%testbentch_module%.vvp" %vivado_lib% %rtl_file% %testbentch_file% %vivado_dir%/glbl.v

以上命令:

  • 设置vivado 2015.3仿真库目录

  • 并通过

    -y
    

    选项列出仿真库各子目录:

    • retarget
    • unifast
    • unimacro
    • unisims
    • xeclib
  • 在iverilog命令中增加了%vivado_dir%/glbl.v,否则IP编译出错

**注意:**以上iverilog中还增加了一个%rtl_file%,为要仿真RTL文件,类似%testbentch_file%的变量需要在之前设置

Lattice

Lattice的库仿真,编译较简单只要指定使用到的芯片的库即可(不同于Xilinx,Lattice各芯片的仿真库不同),只是在仿真测试文件中(如上面例子中的hello_world_tb.v文件)模块中需要例化两个模块:

//  lattice库使用testbentch模块中要加
GSR GSR_INST(.GSR(1'b1));
PUR PUR_INST(.PUR(1'b1));

本机安装Diamond3.5,安装目录在E盘

ECP3

则在使用iverilog编译时使用以下命令即可(替换上面例子中iverilog命令那行)

set lattice_dir=E:\lscc\diamond\3.5_x64\cae_library\simulation\verilog
set ecp3_lib="-y%lattice_dir%\ecp3" "-y%lattice_dir%\pmi"
iverilog -g2012 -o "%testbentch_module%.vvp" %ecp3_lib% %rtl_file% %testbentch_file%

以上命令:

  • diamond 3.5仿真库目录

  • 并通过

    -y
    

    选项列出ECP3芯片仿真库子目录:

    • pmi
    • ecp3

MachOX2

则在使用iverilog编译时使用以下命令即可(替换上面例子中iverilog命令那行)

set lattice_dir=E:\lscc\diamond\3.5_x64\cae_library\simulation\verilog
set machxo2_lib="-y%lattice_dir%\machxo2" "-y%lattice_dir%\pmi"
iverilog -g2012 -o "%testbentch_module%.vvp" %machxo2_lib% %rtl_file% %testbentch_file%

以上命令:

  • diamond 3.5仿真库目录

  • 并通过

    -y
    

    选项列出MachOX2芯片仿真库子目录:

    • pmi(同ECP3)
    • machxo2

注意事项

这里列出我在使用中遇到的一些问题或建议

verilog源码

  • 代码文件名最好为模块名+.v方式,因为通过-y方式指定目录时查找模块时iverilog要求模块名和文件名要相同,否则可能导致无法找到对应模块(这个要求也是平时写verilog应该有的好习惯)
  • testbentch中结束仿真推荐用$finish而不用$stop;因为$finish可以直接结束仿真并退出,而不需要手动退出,这样运行类似以上例子批处理后可以直接打开GTKWave窗口

编译命令

  • iverilog命令中通过-y指定目录时,需要放在源文件参数之前,否则提示有错
  • iverilog命令中通过-D传递宏包含引号的方法:-DIN_FILE="\"xxx.v\"",这在verilog有``include IN_FILE时需要使用;而iverilog命令中使用-DIN_FILE=“xxx.v”`方式有错误
  • 指定源文件时可以用通配符*,如本人用的批处理中通常使用这种方式指定RTL文件:set rtl_file="../rtl/*.v"

其它

  • 加大DOS窗口高度。由于运行批处理需要在DOS窗口查看verilog中$display的打印,有时iverilog编译打印的信息较多时会导致部分信息无法查看,所以需要加大DOS窗口的高度:在DOS窗口标题栏右键->默认值->布局中设置屏幕缓冲区中高度为较大的值(如1000)即可
  • iverilog即使指定为-g2012也不支持break、static等(测试得到)

bash环境适用于iverilog+gtkwave的自动综合脚本

#!/bin/bash

if [ "$1" = "" ]; then
	echo Usage...
	echo "first parameter:"
	echo "command:"
	echo -e "\tclean  com"
	exit
else
	read -p "Project name: " pname
fi

case $1 in
	"")	echo -e "No param input"
		exit;;
	"clean")	rm ${pname}.lxt ${pname}.vvp ${pname} 2> /dev/null
		exit;;
	"com")	echo Synthesize...;;
esac


echo iverilog compiling...
iverilog ${pname}.v ${pname}_tb.v -o ${pname}.vvp
if [ $? -ne 0 ]; then
	echo iverilog synthesize failed
	exit
fi
echo vvp...
vvp -n $pname.vvp -lxt
if [ $? -ne 0 ]; then
	echo $?
	echo vvp failed
	exit
fi
gtkwave $pname.lxt

你可能感兴趣的:(小工具,FPGA,linux,经验分享,fpga,verilog)