You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UVM Driver中如何正确实现阻塞赋值信号到非阻塞赋值的转换?

UVM Driver中阻塞转非阻塞赋值的竞争条件问题解答

首先看你的示例代码:

task run_phase();

vif.addr <=0;

forever begin
    seq_item_port.get_next_item(req);
    //@(posedge vif.CLK);  Need clocking sample to avoid race condition??
    vif.haddr <= req.addr;        
    
    @(posedge vif.CLK iff(vif.READY));

    if(req.rw == READ) begin
        @(posedge vif.CLK iff(vif.READY));
        req.data = vif.hrdata;
    end
    else
        vif.hwdata <= req.data;
end

核心问题分析

你当前的vif.haddr <= req.addr直接在get_next_item后执行,没有和时钟同步,确实存在竞争风险,原因如下:

  • req.addr是来自sequence的阻塞赋值变量,其值可能在任意时间被更新(比如sequence在时钟沿临近时修改req.addr)。
  • SystemVerilog的事件调度顺序中,时钟沿的采样(DUT侧always @(posedge CLK)的信号采样)发生在预触发阶段,而非阻塞赋值的更新发生在NBA阶段。如果你的Driver在时钟沿到来前的活跃阶段执行NBA赋值,DUT在当前时钟沿采样到的会是旧值,新值要等到下一个时钟沿才会生效——这会导致协议时序不匹配,甚至出现不可预测的采样结果。

结论:必须添加时钟同步逻辑

当前写法属于易引发竞争的违规赋值,必须添加时钟采样逻辑来同步输出赋值。正确的调整方式有两种:

方式1:先等待时钟沿,再赋值

确保赋值操作在时钟沿之后执行,让新值在下一个时钟沿被DUT采样:

seq_item_port.get_next_item(req);
@(posedge vif.CLK); // 先同步到时钟沿,避免时序混乱
vif.haddr <= req.addr;        
@(posedge vif.CLK iff(vif.READY));

方式2:将赋值与READY有效时钟沿绑定

如果你的协议要求haddr在READY有效的时钟沿被采样,可以把赋值放在该时钟沿触发后,确保DUT在下一个时钟沿能拿到稳定值:

seq_item_port.get_next_item(req);
@(posedge vif.CLK iff(vif.READY));
vif.haddr <= req.addr;        
// 后续读/写逻辑

额外注意点

  • 对于写操作的vif.hwdata <= req.data,同样需要遵循时钟同步原则,避免直接在无时钟同步的情况下执行NBA赋值。
  • 更规范的做法是在接口中使用clocking block,它会自动帮你处理时钟同步和采样/驱动的时序,从根源上避免竞争条件。

内容的提问来源于stack exchange,提问作者bu-ral

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 10:52:50