文章目录
下载安装
硬件编程最让人无语的就是综合与实现的耗时,这个时间非常微妙,既不像软件开发,一个进度条的时间基本就能搞定,也不像AI调参,可以一行代码调一天,而是刚好卡在十几分钟,几乎啥也做不了。所以,为了让自己尽量少一点浪费时间,事先对verilog的代码进行检查和仿真就显得格外重要,Icarus Verilog就是为此而生。
iVerilog是一款开源免费的Verilog编译器和仿真器,安装时注意勾选将可执行文件夹加入环境变量,安装完成后,可在命令行中用where语句检查下面三个工具是否存在,若安装成功,会返回其对应的路径。
bash
where iverilog
where vvp
where gtkwave
这三个工具的功能为
- 【iverilog】对verilog和VHDL文件进行语法检查,并进行编译,生成可执行文件
- 【vvp】根据可执行文件,生成仿真波形文件
- 【gtkwave】打开仿真波形文件,图形化显示波形
接下来,我们就逐一试用这三个功能
文件准备
我们需要准备一段测试代码和一段仿真代码,前者是我们希望实现的某个功能,后者用于模拟仿真环境,从而对我们的代码进行测试。
以最简单的控制led灯为例,下面代码的功能是,让led每隔15个时钟周期进行亮暗变化。当然,如果真的有LED灯,我们是没发看到这种高频变化的规律的,但从波形仿真的角度来说,这个频率刚好合适。
verilog
module led(
input clk,
input rst_n,
output reg led
);
reg [4:0] cnt;
always @ (posedge clk or negedge rst_n) begin
if(!rst_n)
cnt <= 0;
else
cnt <= cnt==15 ? 0 : cnt+1;
end
always @ (posedge clk or negedge rst_n) begin
if(!rst_n)
led <= 0;
else if(cnt == 15)
led <= !led;
end
endmodule
上述代码需要两个输入信号clk, rst_n和一个输出信号led,那么在仿真环境中,也需要对这三个信号进行定义。代码如下
verilog
`timescale 1ns/100ps
module led_tb;
parameter PERIOD = 10;
reg SYSCLK;
reg NSYSRESET;
initial begin
SYSCLK = 1'b0;
NSYSRESET = 1'b0;
end
/*iverilog */
initial begin
$dumpfile("wave.vcd"); //生成的vcd文件名称
$dumpvars(0, led_tb); //tb模块名称
end
/*iverilog */
initial begin
#(PERIOD * 10 )
NSYSRESET = 1'b1;
#1000
$stop;
end
always @(SYSCLK)
#(PERIOD / 2.0) SYSCLK <= !SYSCLK;
led u_led (
.rst_n(NSYSRESET),
.clk(SYSCLK),
.led( led)
);
endmodule
其中,被/*iverilog*/框起来的区域,是iverilog特有的语法,其中【dumpfile】用于生成波形文件,【dumpvars】指定要记录的波形,0表示记录led_tb模块及其子模块中的所有变量。
仿真
编译和仿真的语句如下
bash
iverilog -o wave led_tb.v led.v
其语法与gcc相似,【-o wave】代表输出名为wave的文件,后面【led_tb.v】和【led.v】即为准备编译的文件。该命令被执行后,同目录下会生成wave文件,该文件可用于生成波形。
生成波形的语句如下
bash
vvp -n wave -lxt2
其中,【-n wave】用于指定生成波形的文件,lxt2是一种二进制格式,可以理解为vcd文件的一种。当执行完该文件后,同级目录下会生成wave.vcd文件,该文件可通过gtkwave打开,以查看波形
bash
gtkwave wave.vcd
弹出gtkwave窗口后,点击SST侧栏中的树形图,则Signal中会出现对应的信号,双击信号,即可将其显示在右侧的波形图中。通过Ctrl键和鼠标滚轮,可以调整波形图的时间坐标,结果如下
