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

如何修改UVM的bit bash序列适配DUT的2周期读写延迟?

解决UVM RegModel适配DUT 2周期读写延迟的问题

嘿,这个问题我之前帮好几个同事踩过坑——核心就是UVM寄存器模型默认假设读写1个周期就能完成,但你的DUT需要2个周期才会实际执行并返回结果,所以uvm_reg_bit_bash_seq这类内置序列写完立刻读,读回的还是旧值,自然就比对失败了。

先看你遇到的典型时序不匹配错误:

Writing a 1 in bit #0 of register "ral_pgm.DIFF_STAT_CORE1" with initial value 'h0000000000000000 yielded 'h0000000000000000 instead of 'h0000000000000001

下面是几种靠谱的解决方式,按全局适配的优先级排序:

1. 给总线适配器/驱动加延迟(推荐全局使用)

寄存器适配器(uvm_reg_adapter)是RegModel和总线之间的翻译器,你可以在总线的driver或者sequence里,添加2个时钟周期的等待,确保DUT完成操作后再继续流程。

比如在总线driver里处理:

class my_bus_driver extends uvm_driver #(my_bus_seq_item);
  virtual task run_phase(uvm_phase phase);
    forever begin
      seq_item_port.get_next_item(req);
      // 先执行总线读写的驱动逻辑
      drive_bus_transfer(req);
      // 关键:等待2个时钟周期,给DUT足够时间完成操作
      repeat(2) @(posedge vif.clk);
      seq_item_port.item_done();
    end
  endtask
endclass

如果你的总线sequence是单独定义的,也可以在sequence的body里加延迟:

class my_bus_rw_seq extends uvm_sequence #(my_bus_seq_item);
  virtual task body();
    my_bus_seq_item req;
    req = my_bus_seq_item::type_id::create("req");
    start_item(req);
    finish_item(req);
    // 等待DUT完成读写的2个周期
    repeat(2) @(posedge p_sequencer.vif.clk);
  endtask
endclass

这种方式的好处是全局生效,所有寄存器的读写都会自动带上延迟,不用逐个修改寄存器。

2. 重写寄存器的do_write/do_read方法(适合特殊寄存器)

如果只有少数几个寄存器需要2周期延迟,直接在寄存器类里重写读写方法就行:

class DIFF_STAT_CORE1_reg extends uvm_reg;
  function new(string name = "DIFF_STAT_CORE1_reg");
    super.new(name, 64, UVM_NO_COVERAGE);
  endfunction

  virtual task do_write(uvm_reg_item rw);
    // 先调用默认的写操作逻辑
    super.do_write(rw);
    // 等待2个时钟周期
    repeat(2) @(posedge get_parent_block().vif.clk);
  endtask

  virtual task do_read(uvm_reg_item rw);
    super.do_read(rw);
    repeat(2) @(posedge get_parent_block().vif.clk);
  endtask
endclass

这种方式更灵活,适合单个寄存器有特殊时序的场景。

3. 用UVM内置的访问延迟参数(需要适配器支持)

UVM提供了set_access_delay方法,可以给寄存器或整个block设置访问延迟:

// 在RegModel的build_phase里配置
ral_pgm.DIFF_STAT_CORE1.set_access_delay(2, UVM_WRITE);
ral_pgm.DIFF_STAT_CORE1.set_access_delay(2, UVM_READ);
// 或者给整个PGM block的所有寄存器都设置
ral_pgm.set_access_delay(2, UVM_WRITE | UVM_READ);

不过要注意,这个参数不会自动生效,你需要在总线适配器或driver里读取这个延迟值,然后等待对应的周期:

// 在adapter的reg2bus方法里获取延迟
int delay = rw.reg.get_access_delay(rw.kind);
// 然后在driver里等待delay个周期
repeat(delay) @(posedge vif.clk);

最后验证

调整完之后,再跑uvm_reg_bit_bash_seq,序列就会等待足够的时间再读回寄存器值,自然就能通过比对了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:34:48