2

我想在我的 uvm_sequencer 的 run_phase 中获取事务以检查事务是否跨越 4KB 边界。如果他们跨越 4KB 边界,我想将该事务拆分为多个事务,然后将其发送给驱动程序。当收到来自驱动程序的响应时,所有拆分事务响应应合并回原始事务并返回到生成原始事务的序列。有没有办法做到这一点?uvm_sequencer 是否适合做这项工作?任何帮助将不胜感激。

编辑:

Tudor 的解决方案确实有效。我对他的代码(translation_sequence)添加了一些编辑,如下所示:

up_sequencer.get_next_item(req);
$cast(up_trans, req.clone());
// do the splitting.
start_item(up_trans);
finish_item(up_trans);
up_sequencer.item_done();
get_response(rsp);
rsp.set_sequence_id(req.get_sequence_id());
up_sequencer.put_response(rsp);
4

1 回答 1

2

您不能在音序器中执行此操作,因为发送项目分两步执行:start_item(...)finish_item(...). 如果它只是一种方法,你可以在那里完成。

IMO,要走的路是实施分层方案。您的上层是您开始序列的地方,您不关心事务的长度。您的第二层是最大长度为 4K 的层。交易流程将是:

你的序列 -> 上序列器 -> 翻译序列 -> 总线序列器 -> 驱动程序

这意味着在您的代理中,您将需要两个定序器,其中只有一个连接到驱动程序。翻译序列可能如下所示:

class translation_sequence extends uvm_sequence #(some_trans);
  uvm_sequencer #(some_trans) up_sequencer;

  task body();
    while (1) begin
      some_trans up_trans;
      up_sequencer.get_next_item(up_trans);

      if (up_trans.size <= 4096) begin
        `uvm_info("SPLIT", "No need to split", UVM_LOW);
        start_item(up_trans);
        finish_item(up_trans);
      end
      else begin
        // implement the splitting
        int unsigned size = up_trans.size;

        while (1) begin
          req = new();
          req.size = size > 4096 ? 4096 : size;
          start_item(req);
          finish_item(req);

          if (size < 4096)
            break;
          else
            size -= 4096;
        end
      end

      up_sequencer.item_done();
    end
  endtask
endclass

请注意,它有一个指向上层排序器的指针,它从中获取项目并发出完成信号。在代理中,您需要启动这个序列,同时给它一个指向上层序列器的指针:

class some_agent extends uvm_agent;
  //...

  // start the translation sequence
  task run_phase(uvm_phase phase);
    translation_sequence seq = new();
    seq.up_sequencer = sequencer;
    seq.start(bus_sequencer);
  endtask
endclass

如果您想了解更多关于分层的信息,请查看这篇关于Verification Horizo​​ns的文章。

于 2014-11-23T02:55:05.890 回答