Verilog 激励文件(TestBench)常用语法速查

发布时间:2026/9/14 21:52:29
Verilog 激励文件(TestBench)常用语法速查 Verilog 激励文件TestBench常用语法速查在 FPGA 开发中编写 TestBench 是验证设计功能的关键环节。无论是简单的 LED 闪烁工程还是复杂的 SoC 系统一个好的 TestBench 都能帮你快速定位问题、验证逻辑正确性。本文整理了 Verilog TestBench 编写中最常用的语法和技巧适合作为日常开发时的速查手册。一、时间与时钟1.1 时间尺度文件首行必写timescale 1ns / 1ps含义时间单位为 1ns精度为 1ps单位/精度可换成1ps、10ns等但要与仿真时长匹配1.2 时钟生成推荐写法initial begin clk 1b0; // 先给初值 forever #(CLK_PERIOD/2) clk ~clk; // 每半个周期翻转一次 end1.3 延时##10; // 延时 10 个时间单位 #(CLK_PERIOD*2); // 延时 2 倍时钟周期 #5ns; // 延时 5 纳秒二、赋值赋值方式符号特点适用场景阻塞赋值立即生效组合逻辑 / 激励赋值非阻塞赋值采样后再更新时钟驱动的数据经验法则TestBench 中给激励信号赋值一般用阻塞赋值描述被测模块内部时序逻辑时用非阻塞赋值。三、激励结构3.1initial块只执行一次激励主战场initial begin rst_n 1b0; // 复位有效 #20; // 持续 20 时间单位 rst_n 1b1; // 释放复位 end3.2always块持续执行always #5 clk ~clk; // 也常用来生成时钟需先赋初值3.3 任务task封装可复用逻辑task wait_cycles(input integer n); repeat(n) (posedge clk); // 等待 n 个上升沿 endtask3.4 事件等待(...)(posedge clk); // 等待上升沿 (negedge rst_n); // 等待下降沿 repeat(5) (posedge clk); // 等待 5 个上升沿四、检查与打印自检核心4.1$display打印信息$display(time%0t led%b, $time, led);常用格式符格式符含义%0t时间%b二进制%0d十进制%h十六进制4.2$monitor信号变化时自动打印$monitor(%0t led%b, $time, led);4.3$finish结束仿真$finish;4.4 自检判断典型写法if (led ! 1b1) begin $display(FAIL %0t, $time); $finish; end五、控制流if / else // 条件分支 repeat(n) // 重复 n 次 for (i0; iN; ii1) // 循环 while (cond) // 条件循环 case // 多路选择六、波形输出initial begin $dumpfile(tb_led_flash.vcd); // 波形文件名 $dumpvars(0, tb_led_flash); // 0记录顶层及其下所有信号 end生成的.vcd文件可以用 GTKWave 等工具打开查看波形。七、参数化localparam CLK_PERIOD 10; // 只在本模块可见 localparam CNT_MAX 26d49_999_999;parameter可被上层覆盖localparam不能TestBench 里一般用localparam即可八、随机激励数据通路验证常用reg [7:0] d; d $random % 256; // 0~255 随机数 d $random(seed); // 带种子结果可复现九、最常用的三件套核心用法forever生成时钟initial/task给激励$display/$finish做自检$dumpvars出波形十、仿真控制与调试进阶10.1$stop暂停仿真$stop;可用交互命令继续或退出。10.2$fwrite/$fopen往文件写激励或结果integer fd; fd $fopen(out.txt, w); // 打开文件w写 $fwrite(fd, %0t led%b\n, $time, led); // 写一行到文件 $fclose(fd); // 关闭文件10.3force/release强制或释放信号值调试用force dut.signal 1b1; release dut.signal;10.4timescale可单独给不同模块设不同时间尺度timescale 1ns/1ps timescale 10ns/1ns10.5 负数与位宽明确位宽避免截断reg [31:0] cnt; cnt 32hFFFF_FFFF; // 下划线可读性好 // 带 _ 的数字分隔符26d49_999_999十一、SystemVerilog 语法iverilog 加-g2012才支持11.1logic类型替代reg/wire推荐logic clk; logic [7:0] data;11.2always_comb/always_ff明确意图always_ff (posedge clk) // 时序 always_comb // 组合11.3interface/modport端口封装复杂验证时把一组信号封装成 interface 供多个模块复用。11.4class/virtual interface面向对象验证UVM 等验证方法学的核心工作量大简单 TB 不需要。11.5task带默认参数、ref参数task wait_cycles(input int n 10); // 默认参数 task my_task(ref logic [7:0] d); // 引用参数可修改外部变量11.6typedef/enum类型定义typedef enum logic [1:0] {IDLE, RUN, DONE} state_t;11.7assert property断言SVA描述时序属性如led 翻转间隔固定用于并发断言检查。十二、一般用不到的类型简单 TB 可忽略generate/genvar按参数生成结构层次化引用通过顶层路径读取任意信号如tb_led_flash.u_dut.cntgenerate循环根据宏或参数批量例化需谨慎总结场景推荐语法生成时钟forever #(period/2) clk ~clk给激励initial块 阻塞赋值等待信号(posedge clk)/repeat(n)打印调试$display/$monitor结束仿真$finish输出波形$dumpfile$dumpvars自检判断if (sig ! expected)$display(FAIL)掌握以上语法基本可以覆盖日常 FPGA 开发中 90% 以上的 TestBench 编写需求。建议收藏本文编写 TB 时随时查阅。