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

Specman的sys.tick_end()在SystemVerilog中的等效实现及同步方案问询

SystemVerilog中实现类似Specman sys.tick_end()的同步方案

问题描述

我有一套基于参考模型(reference model)做检查的SystemVerilog代码,该参考模型由监视器的多个分析端口(analysis ports)并行更新,同时供检查器(checker)读取。共享参考模型包含大量数据对象,检查器需要在同一周期查看多个对象。

由于监视器任务与检查器任务的执行顺序无法保证,检查器可能读取到参考模型的过期值。我需要同步检查器,使其等待当前周期内监视器analysis ports的所有事务完成对参考模型的更新后再执行。

此前使用Specman时,可通过在检查器中调用sys.tick_end()解决此类问题,该方法能确保检查器代码在当前周期末尾执行,即所有端口监视器完成参考模型更新之后。

请问SystemVerilog中是否存在Specman的sys.tick_end()的等效实现?或者是否有其他方法可同步检查器,使其等待当前周期内所有监视器完成更新?


解决方案

1. 时钟沿后添加#0延迟

在检查器任务中,先等待时钟上升沿,再加入#0延迟。#0会让当前线程暂停,直到同一时间步的所有其他线程(包括监视器的分析端口处理任务)执行完毕后再继续执行检查逻辑。示例代码:

task run_checker();
  forever begin
    @(posedge clk);
    #0; // 等待同一时间步内所有更新操作完成
    // 执行参考模型检查逻辑
    check_reference_model();
  end
endtask

2. 利用program块的final块

如果检查器基于program块实现,可以借助final块。final块会在当前时间步的所有非阻塞赋值、任务/函数执行完成后,时间步结束前触发。注意结合循环实现周期性检查:

program checker_prog(input clk);
  initial begin
    forever begin
      @(posedge clk);
      final begin
        // 检查逻辑写在此处
        check_reference_model();
      end
    end
  end
endprogram

3. 事件触发同步所有监视器

让每个监视器在完成参考模型更新后触发一个事件,检查器等待所有事件触发后再执行检查。可以用动态事件队列实现:

event monitor_update_done[$];

// 监视器侧代码
task monitor_write(transaction tr);
  // 更新参考模型
  ref_model.update(tr);
  -> monitor_update_done.push_back();
endtask

// 检查器侧代码
task run_checker();
  forever begin
    @(posedge clk);
    // 等待所有监视器完成更新
    foreach (monitor_update_done[i]) wait(monitor_update_done[i]);
    // 清空事件队列,为下周期做准备
    monitor_update_done.delete();
    // 执行检查
    check_reference_model();
  end
endtask

4. UVM框架下的相位或屏障同步

如果验证环境基于UVM,可利用框架自带的同步机制:

  • 用uvm_check_phase执行检查:UVM会保证所有uvm_monitor的run_phase更新任务在check_phase前完成;
  • 用uvm_barrier同步:设置屏障等待所有监视器完成更新后,检查器再执行逻辑。示例代码:
uvm_barrier update_barrier;

// 监视器run_phase任务
task run_phase(uvm_phase phase);
  forever begin
    // 接收事务并更新参考模型
    ref_model.update(tr);
    update_barrier.wait_for();
  end
endtask

// 检查器check_phase任务
task check_phase(uvm_phase phase);
  forever begin
    @(posedge clk);
    update_barrier.set_num_waiters(NUM_MONITORS); // 设置需要等待的监视器数量
    update_barrier.wait_for();
    // 执行检查
    check_reference_model();
    update_barrier.reset();
  end
endtask

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 23:10:31