仿真与自检 Testbench
验证目标
跳转到“验证目标”Testbench 不应只“产生一条能看的波形”,而应自动判断结果并在失败时给出时间、输入和期望值。
module counter_tb; timeunit 1ns; timeprecision 1ps;
logic clk = 1'b0; logic rst = 1'b1; logic enable; logic [3:0] count;
always #5ns clk = ~clk;
counter #(.WIDTH(4)) dut (.*);
initial begin enable = 1'b0; repeat (2) @(posedge clk); rst <= 1'b0;
enable <= 1'b1; repeat (3) @(posedge clk); #1step; assert (count == 4'd3) else $fatal(1, "count=%0d, expected 3", count);
$finish; endendmodule推荐结构
跳转到“推荐结构”flowchart LR GEN["激励生成"] --> DUT["DUT"] --> MON["监视器"] --> CHECK["参考模型 / 断言"] GEN --> CHECK- 驱动器:只在约定的时钟相位改变输入,避免竞态。
- 监视器:采集接口事务,不依赖内部实现。
- 参考模型/计分板:计算期望结果并比较。
- 断言:检查握手、稳定性、互斥、延迟和“不应发生”的事件。
最小覆盖集
跳转到“最小覆盖集”- 复位期间和复位释放后的第一笔事务。
- 最小值、最大值、计数回绕和位宽边界。
- 连续事务、空闲间隔、背压与突发。
- 错误输入、超时和恢复。
- 状态机的每条合法转移。
- CDC/FIFO 的两个时钟采用不同频率和相位。
常见问题
跳转到“常见问题”- 只检查最终结果,漏掉协议时序和中间丢数。
- 在采样边沿同时改变输入,造成测试台与 DUT 的竞态。
- 使用固定延时等待功能完成;优先等待握手或事件,并设置超时。
- 波形中出现
x就强制为 0;应先定位未复位、越界或多驱动。 - 行为仿真通过后不看综合警告、时序和 CDC 报告。