非阻塞驱动程序 - 定序器模型

时间:2015-03-27 05:56:14

标签: system-verilog uvm

我通常有一个典型的驱动程序 - 定序器通信机制如下:

// somewhere in driver run_phase
seq_item_port.get(req_item);
$cast(rsp_item, req_item.clone());
// ... execute the item
seq_item.port.put(rsp_item);

执行项目时,可能存在需要驱动程序暂停执行直到满足特定事件的条件。当事件满足时,驱动程序可以恢复并完成执行。 在暂停期间,驱动程序应该能够执行序列发送器发送的其他sequence_item。

显然,上述代码无法处理这种情况。所以我想我需要在音序器和驱动程序之间使用某种非阻塞机制。 由于我之前从未这样做过,所以我想知道是否有一个示例或标准使用模型/机制来执行此操作。

1 个答案:

答案 0 :(得分:1)

您必须在驱动程序中以及在顺控程序上运行的顺序中实现这两种类型。

在驱动程序中,您需要做一些分叉。由于我无法确切地知道你想做什么,所以我会写一些通用的东西:

class some_driver;
  task run_phase(uvm_phase phase);
    forever begin
      seq_item_port.get(req);
      $cast(rsp, req.clone());
      fork
        if (<some_condition_here>) begin
          drive(req);
          seq_item.port.put(rsp);
        end
      join_none
    end
  endtask
endclass

<some_condition>可以取决于被驱动的项目,系统的状态或两者。您的驱动程序将快速从顺控程序中获取项目并按自己的进度驱动它们。

按照正在运行的顺序,您还必须通过分叉来实现并行性:

class some_sequence;
  task body();
    // item1 has to be finished completely before going further
    start_item(item1);
    finish_item(item1);
    get_response(item1);

    // item2 has to start before item3, but it doesn't matter which is done first
    start_item(item2);
    finish_item(item2);

    start_item(item3);
    finish_item(item3);

    fork
      begin
        get_response(item2);
        get_response(item3);
      end
    join
  endtask
endclass

您可以实施各种疯狂的场景。同样,这一切都非常通用,但它应该是实现自己的代码的起点。