跳转至

输入查询内容

    本页内容

    Push sequencer 第二笔请求失败

    环境:VCS W-2024.09-SP2-8。1.2 使用 uvm-1.2,2.0 使用 uvm-ieee-2020-2.0

    实验检查观察值是否符合预期;成功复现问题不代表问题已修复。

    修改前后对比

    观察内容 1.2 旧写法 2.0 旧写法 1.2 改写后 2.0 改写后
    driver 实际收到的 push 请求数 push_count 2 2 2 2
    driver 收到的第一笔请求值 push_first 1 1 1 1
    driver 收到的第二笔请求值 push_second 2 1 2 2
    sequence 执行完成(1=是) sequence_completed 1 1 1 1
    请求 FIFO 满导致的报错数 request_fifo_full_errors 0 1 0 0

    运行命令

    目录与环境准备;从解包根目录执行:

    uv run tools/run_uvm_review.py --case push_probe --variants 12,20
    

    改写后运行命令

    uv run tools/run_uvm_review.py --case push_probe --variants 12,20 --plusarg +MIGRATED --check tests/uvm_review/push_migrated.expected.json
    

    最小源码

    push_probe.sv

    push_probe.sv
    `timescale 1ns/1ps
    `include "uvm_macros.svh"
    import uvm_pkg::*;
    
    class push_item extends uvm_sequence_item;
      int value;
      function new(string name="item"); super.new(name); endfunction
    endclass
    class push_catcher extends uvm_report_catcher;
      int full_errors;
      function new(); super.new("push_catcher"); endfunction
      function action_e catch();
        if (get_id() == "SQRSNDREQGNI") begin
          full_errors++;
          // Keep observing after the known fatal; this is test instrumentation only.
          return CAUGHT;
        end
        return THROW;
      endfunction
    endclass
    class push_sequence extends uvm_sequence#(push_item);
      bit completed;
      function new(string name="seq"); super.new(name); endfunction
      task body();
        for (int i=1; i<=2; i++) begin
          req = new(); req.value = i;
          start_item(req); finish_item(req);
        end
        completed = 1;
      endtask
    endclass
    class push_sink extends uvm_component;
      uvm_blocking_put_imp#(push_item,push_sink) input_port;
      int values[$];
      function new(string name, uvm_component parent);
        super.new(name,parent); input_port = new("input_port",this);
      endfunction
      task put(push_item item); values.push_back(item.value); #1; endtask
    endclass
    class repaired_push_sequencer extends uvm_push_sequencer#(push_item);
      function new(string name, uvm_component parent); super.new(name,parent); endfunction
      task run_phase(uvm_phase phase);
        push_item item;
        if (!$test$plusargs("MIGRATED")) super.run_phase(phase);
        else forever begin
    `ifdef REVIEW_UVM20
          m_safe_select_item(0,item);
          sequence_item_requested = 0;
          // Consume the request peeked by m_safe_select_item before selecting again.
          if (!m_req_fifo.try_get(item)) `uvm_fatal("PUSH_DRAIN", "No selected item")
    `else
          m_select_sequence();
          m_req_fifo.get(item);
    `endif
          req_port.put(item);
          m_wait_for_item_sequence_id = item.get_sequence_id();
          m_wait_for_item_transaction_id = item.get_transaction_id();
        end
      endtask
    endclass
    class push_test extends uvm_test;
      `uvm_component_utils(push_test)
      repaired_push_sequencer sqr;
      push_sink sink;
      function new(string name, uvm_component parent); super.new(name,parent); endfunction
      function void build_phase(uvm_phase phase);
        super.build_phase(phase); sqr = new("sqr",this); sink = new("sink",this);
      endfunction
      function void connect_phase(uvm_phase phase); sqr.req_port.connect(sink.input_port); endfunction
      task run_phase(uvm_phase phase);
        push_sequence sequence_value = new();
        push_catcher catcher = new();
        uvm_report_cb::add(sqr,catcher);
        phase.raise_objection(this);
        fork sequence_value.start(sqr); join_none
        #10;
        $display("REVIEW|push_count|%0d", sink.values.size());
        $display("REVIEW|push_first|%0d", sink.values.size() > 0 ? sink.values[0] : -1);
        $display("REVIEW|push_second|%0d", sink.values.size() > 1 ? sink.values[1] : -1);
        $display("REVIEW|sequence_completed|%0d", sequence_value.completed);
        $display("REVIEW|request_fifo_full_errors|%0d", catcher.full_errors);
        sequence_value.kill();
        $display("REVIEW|done|1");
        phase.drop_objection(this);
      endtask
    endclass
    module push_probe;
      initial run_test("push_test");
    endmodule
    

    全部用例 · 证据摘要

    版本适用范围