跳转至

输入查询内容

    本页内容

    driver 等待请求时 kill sequence:核对后续仲裁

    影响范围

    堆叠 sequencer,或在 get_next_item/try_next_item 等待时 kill sequence。

    具体差异

    旧行为——赢得仲裁的 sequence 若在 send_request 前被 kill,driver 的 get_next_item/peek 可能挂死,try_next_item 报 null item;新行为——检测 process_id.status 为 KILLED/FINISHED 时自动重新仲裁。堆叠 sequencer(sequencer 套 sequencer)需对底层 sequencer 设置 uvm_config_db#(int)::set(..., "wait_for_sequences_count", N),否则 try_next_item 可能取不到 item。

    修改方案

    普通请求等待流程可保留。存在多级 sequencer 堆叠时,在目标 sequencer 的 build_phase 读取配置之前,通过 uvm_config_db#(int)::set 配置其 wait_for_sequences_count,逐级验证计数满足传播需要;kill 等待中的 sequence 后,检查下一笔请求仍能被 driver 消费。具体配置读取位置见源码依据,不把固定延迟当通用补偿。

    兼容措施与范围:现有入口无需兼容开关;这不表示两版行为相同,仍按本条条件和验证方法核对。

    迁移后验证

    kill 等待者后再发新请求,检查重新仲裁、完成计数及等待上限;堆叠时按实际层数检查 wait_for_sequences_count。

    记录本条结果M06-012 · 状态与证据

    已有实测与复现

    补充查阅

    扫描定位与记录结果

    有扫描规则,覆盖部分可识别写法。脚本检查名称、参数和部分 FLAG 表达式,并对少数直接声明关联使用点;未做完整类型解析或预处理,行为结果仍需验证。

    • S34 · 启发式:sequence lock/kill 与等待请求流程。 排除已识别的 process/component 接收者;未知类型仍保留启发式提示。扫描不能证明并发竞争与 kill 时序。
    uv run tools/uvm_migration_scan.py <SoC代码目录> --rules S34
    

    核对命中对象及生效分支后,在条目清单记录修改与验证证据;扫描规则记录用于整理命中位置。

    扫描器下载、输入范围与报告说明

    源码与标准依据

    核查方式:源码与实测核对。实测仅覆盖本条所列场景。

    VCS 内置 UVM-1.2uvm_sequencer.svh:230(try_next_item 一次 wait_for_sequences 后未取到 item 即报 TRY_NEXT_BLOCKED 返回 null)

    VCS 内置 uvm-ieee-2020-2.0uvm_sequencer.svh:225uvm_sequencer_param_base.svh:474–506(新增 m_safe_select_item)、uvm_sequencer_base.svh:76/uvm_sequencer_base.svh:442–447wait_for_sequences_count config_db 配置,默认 1)

    引用代码(高亮为引用行);上方行号链接可直接定位。

    src/vcs-uvm-1.2/seq/uvm_sequencer.svh
    // try_next_item
    // -------------
    
    task uvm_sequencer::try_next_item(output REQ t);
      int selected_sequence;
      time arb_time;
      uvm_sequence_base seq;
    
      if (get_next_item_called == 1) begin
        uvm_report_error(get_full_name(), "get_next_item/try_next_item called twice without item_done or get in between", UVM_NONE);
        return;
      end
    
      // allow state from last transaction to settle such that sequences'
      // relevancy can be determined with up-to-date information
      wait_for_sequences();
    
      // choose the sequence based on relevancy
      selected_sequence = m_choose_next_request();
    

    完整源码 · SHA256:6d2daeebf191b44e352885f8dba22a841298a245ea6facb5f7e56e1775d5ce17

    src/vcs-uvm-ieee-2020-2.0/seq/uvm_sequencer.svh
    // try_next_item
    // -------------
    
    task uvm_sequencer::try_next_item(output REQ t);
      int selected_sequence;
      uvm_sequence_request selected_sequence_request;
      bit found_item;
      time arb_time;
    
      if (get_next_item_called == 1) begin
        uvm_report_error(get_full_name(), "get_next_item/try_next_item called twice without item_done or get in between", UVM_NONE);
        return;
      end
    
      // allow state from last transaction to settle such that sequences'
      // relevancy can be determined with up-to-date information
      repeat (m_wait_for_sequences_count) begin
        wait_for_sequences();
    

    完整源码 · SHA256:c4cb26775fb9b6be1a06f04045ccd8a81f7c20730e505e5e08596a47f6de096d

    src/vcs-uvm-ieee-2020-2.0/seq/uvm_sequencer_param_base.svh
    // m_safe_select_item
    // ---------------------
    
    task uvm_sequencer_param_base::m_safe_select_item(input bit get_next_item, output REQ t);
      process select_process;
      uvm_sequence_request selected_sequence_request;
      if(sequence_item_requested == 0) begin
        m_select_sequence(selected_sequence_request);
        fork
          begin
            select_process = process::self();
            // re-arbitrate if the sequence was killed or finished after it won arbitration but before it was
            // able to send its request.
            forever begin
              selected_sequence_request.process_id.await();
    
              if(!m_req_fifo.is_empty())
                break;
    
              if (arb_completed.exists(selected_sequence_request.request_id)) begin
                arb_completed.delete(selected_sequence_request.request_id);
              end
              m_select_sequence(selected_sequence_request);
            end
          end
        join_none
        // wait for thread to start to ensure it gets killed when peek returns
        wait(select_process != null);
      end
      sequence_item_requested = 1;
      if (get_next_item)
        get_next_item_called = 1;
      m_req_fifo.peek(t);
      if ((select_process != null) && (select_process.status != process::FINISHED))
        select_process.kill();
    endtask
    

    完整源码 · SHA256:99707a7f2e520940931db3c21cd4809bb8dfa57b324007b95501a62fbd4e1d31

    src/vcs-uvm-ieee-2020-2.0/seq/uvm_sequencer_base.svh
      local static int              g_sequence_id = 1;
      local static int              g_sequencer_id = 1;
    
      protected int                 m_wait_for_sequences_count;  // specifies the # of times the sequencer
                                                                 // should call wait_for_sequences().  A
                                                                 // value > 1 allows sequencer stacking.
      // Function -- NODOCS -- new
      //
      // Creates and initializes an instance of this class using the normal
      // constructor arguments for uvm_component: name is the name of the
      // instance, and parent is the handle to the hierarchical parent.
    
      // @uvm-ieee 1800.2-2020 auto 15.3.2.1
      extern function new (string name, uvm_component parent);
    
      // Variable: wait_for_sequences_count
      // Controls the number of wait_for_sequences calls when selecting next sequence.
      //
      // By default, the sequencers will wait for 1 ~wait_for_sequences~ call
    

    src/vcs-uvm-ieee-2020-2.0/seq/uvm_sequencer_base.svh
    // -----------
    function void uvm_sequencer_base::build_phase(uvm_phase phase);
      super.build_phase(phase);
      if (!uvm_config_db#(uvm_bitstream_t)::get(this, "", "wait_for_sequences_count", m_wait_for_sequences_count))
        void'(uvm_config_db#(int)::get(this, "", "wait_for_sequences_count", m_wait_for_sequences_count));
    
      if (m_wait_for_sequences_count < 1) begin
        `uvm_warning("UVM/SQR/WFSC", $sformatf("attempt to set wait_for_sequences_count to '%0d' will be ignored, values must be 1 or greater!", m_wait_for_sequences_count))
        m_wait_for_sequences_count = 1;
      end
    endfunction : build_phase
    
    // do_print
    // --------
    
    function void uvm_sequencer_base::do_print (uvm_printer printer);
      super.do_print(printer);
      printer.print_array_header("arbitration_queue", arb_sequence_q.size());
      foreach (arb_sequence_q[i])
    

    完整源码 · SHA256:6d2477484529dad661a38b31619edf9898bfa3375f217f06a27b3a69af32ccf7

    术语解释 · 兼容配置

    返回Sequence / Sequencer · 迁移清单

    版本适用范围