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

UVM驱动无法在连续时钟周期发送数据,求解决方法

问题分析与解决方案

问题根源

你的UVM驱动无法在ready持续为高时逐周期发送事务,核心原因是:

  • 驱动valid后多余等待了一个时钟上升沿,直接浪费了一个周期
  • 拉低valid的时机与握手完成的时钟沿不同步,导致额外的周期消耗

原代码时序(ready=1时):

  1. 时钟沿1:驱动valid=1、addr、data
  2. 时钟沿2:无意义等待(无任何操作)
  3. 时钟沿3:采样到ready=1,拉低valid=0
  4. 返回run_phase获取下一个事务,又要等待下一个时钟沿才能驱动,最终间隔两个周期才发送下一个事务

修正后的驱动代码

virtual task run_phase(uvm_phase phase);
  forever begin
    seq_item_port.get_next_item(trans);
    drive(trans);
    seq_item_port.item_done;
  end
endtask

virtual task drive(packet trans);
  // 等待时钟上升沿,驱动事务信号
  @(posedge vif.mod_p.cb);
  vif.mod_p.cb.valid <= 'b1;
  vif.mod_p.cb.addr <= trans.addr;
  vif.mod_p.cb.data <= trans.data;

  // 等待DUT的ready信号(在时钟上升沿采样)
  while(!vif.mod_p.cb.ready) begin
    @(posedge vif.mod_p.cb);
  end

  // 握手完成后,在下一个时钟沿拉低valid(适配多数协议的时序要求)
  @(posedge vif.mod_p.cb);
  vif.mod_p.cb.valid <= 'b0;
endtask

严格逐周期发送的优化方案

如果协议要求握手完成后立即在下一个时钟沿发送下一个事务,可以进一步调整逻辑,将拉低valid的操作和握手完成放在同一时钟沿,避免额外等待:

virtual task drive(packet trans);
  // 驱动事务并等待握手
  @(posedge vif.mod_p.cb);
  vif.mod_p.cb.valid <= 'b1;
  vif.mod_p.cb.addr <= trans.addr;
  vif.mod_p.cb.data <= trans.data;

  // 等待ready响应
  while(!vif.mod_p.cb.ready) begin
    @(posedge vif.mod_p.cb);
  end

  // 握手完成的同一时钟沿拉低valid,确保下一个事务能在下一周期立即驱动
  vif.mod_p.cb.valid <= 'b0;
endtask

这种情况下,当ready持续为高时,每个事务仅占用一个时钟周期(驱动并完成握手),下一个事务会在下一个时钟沿立即驱动,实现真正的逐周期发送。


内容的提问来源于stack exchange,提问作者Grace90

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 00:10:21