如何在SystemVerilog类中生成符合指定规则的带毛刺信号?
在SystemVerilog驱动类中为信号添加跳变沿毛刺的高效实现方案
核心实现思路
针对你需要在驱动类中为干净信号的上升/下降沿插入随机毛刺的需求,核心逻辑是:实时检测输入信号的跳变事件,在跳变触发后按照指定规则生成随机毛刺,最终保证信号稳定在目标电平。整个过程完全在SystemVerilog类中实现,结合随机约束灵活控制毛刺参数。
具体代码实现
下面是完整的驱动类代码,适配你提到的“1-5ms毛刺时长、最多30次”规则:
// 定义与DUT匹配的接口 interface dut_if; logic clk; logic dut_input; endinterface class glitch_driver; virtual interface dut_if vif; // 毛刺控制参数 rand int glitch_count; rand int glitch_duration_ms; // 约束毛刺范围:次数1~30,时长1~5ms constraint glitch_param_c { glitch_count inside {[1:30]}; glitch_duration_ms inside {[1:5]}; } function new(virtual interface dut_if v); vif = v; endfunction // 核心任务:接收干净信号,添加毛刺后驱动到DUT task drive_with_glitch(input logic clean_signal); logic last_signal; last_signal = clean_signal; forever begin @(posedge vif.clk); // 基于时钟采样,避免误检测 // 检测上升沿/下降沿跳变 if (clean_signal != last_signal) begin // 生成指定次数的毛刺 repeat(glitch_count) begin // 翻转信号产生毛刺 vif.dut_input = ~clean_signal; #(glitch_duration_ms * 1ms); // 维持毛刺时长 // 切回目标电平 vif.dut_input = clean_signal; // 可选:添加0~1ms的随机间隔,贴近真实场景 #($urandom_range(0, 1) * 1ms); end // 最终确保信号稳定在目标电平 vif.dut_input = clean_signal; end else begin // 无跳变时直接驱动原信号 vif.dut_input = clean_signal; end last_signal = clean_signal; end endtask endclass
关键细节说明
- 随机约束灵活性:通过
rand变量和约束块,可随时调整毛刺的次数、时长范围,甚至添加定向规则(比如只在上升沿生成毛刺)。 - 时钟同步检测:基于时钟边沿采样信号跳变,避免仿真中异步信号导致的误检测,同时贴近FPGA实际采样逻辑。
- 电平稳定性保证:每次毛刺翻转后切回目标电平,最后再强制赋值一次,确保信号最终稳定在预期状态,不影响后续正常逻辑。
- 可扩展性:如果需要模拟缓慢升降沿,可在跳变时刻添加多级延迟的电平渐变(比如分10步从0到1,每步延迟0.1ms),只需替换毛刺生成逻辑即可。
测试台使用示例
module tb; dut_if if(); glitch_driver drv; logic clean_key; // 测试台生成的干净按键信号 initial begin drv = new(if); drv.drive_with_glitch(clean_key); end endmodule
内容的提问来源于stack exchange,提问作者David Belohrad
相关产品推荐
相关产品推荐

