逻辑设计新人
我当初也是从学生时代用Icarus Verilog+GTKWave过来的,调试效率确实是个痛点。我的核心建议是:用Makefile或Shell脚本把整个流程自动化。
痛点在于,每次修改代码都要手动敲好几条命令:编译、仿真生成波形文件、打开GTKWave。效率很低,还容易敲错。
我的做法是写一个简单的Makefile。比如,你可以定义一个目标“sim”,里面写好“iverilog -o sim.out tb.v design.v”和“vvp sim.out”。再定义一个目标“wave”,直接调用“gtkwave dump.vcd &”。这样,改完代码只需要“make sim && make wave”,一键完成编译、仿真和打开波形。
更进一步,你可以在testbench里用宏或参数控制是否生成波形文件。比如,定义一个`define DUMP_WAVE,在initial块里用`ifdef包裹`$dumpfile`和`$dumpvars`。平时快速调试可以关掉波形生成(跑得快),需要仔细看波形时再打开。
对于testbench文件结构,建议把测试激励(stimulus)、参考模型(reference model)和结果检查(checker)分开到不同的`task`或`module`里。主testbench文件只做例化和调用。这样结构清晰,修改起来也方便。
打印调试的话,别只用`$display`。用`$timeformat`先设置一下时间格式,比如`$timeformat(-9, 0, " ns", 10);`,这样打印出来的时间戳好看又好懂。关键信号变化可以用`$monitor`,但注意它通常全局用一个就够了,别重复调用。
GTKWave保存信号分组,这个很多人不知道。你把信号拖到分组里,调整好颜色和顺序后,在“File”菜单里选择“Write Save File”,保存成一个.gtkw文件。下次直接用“gtkwave dump.vcd saved.gtkw”打开,所有分组和设置都恢复了。
最后一个小技巧:iverilog的编译错误信息有时不太友好。养成先“iverilog -tnull -Wall”做语法检查的习惯,没问题了再仿真,能省去一些无谓的等待。
