如何从另一个序列访问随机序列_item?

时间:2014-12-15 15:30:00

标签: system-verilog uvm

我有一个测试平台,我有两个序列:sequenceA和sequenceB及其相应的序列项(sqitemA和sqitemB)。 sequenceA输入到我的DUT并随机生成sqitemA的值。

现在,我需要访问sqItemA中的一些生成的随机字段,为我的sequenceB创建一个相关的sqItemB。

UVM是否提供了执行此操作的机制?

例如:

class sequenceA extends uvm_sequence;
  rand logic[31:0] address;
  rand bit         enable;

  // skipping constructor 

  task body;
      this.randomize();
      // do body stuff
  endtask
endclass

class sequenceB extends uvm_sequence;
  rand logic[31:0] address;
  rand bit         enable;

  // skipping constructor

  task body;
      // here I want this.address to match the address randomly generated in sequenceA
      // wait_till_sequenceA randomization is complete
      // this.address = sequenceA.address (??);
      // do body stuff
  endtask
endclass

有关最佳方法的任何线索吗?

2 个答案:

答案 0 :(得分:2)

如果要跨多个序列同步流量,最好的办法是使用虚拟序列:

class virtual_seq extend uvm_sequence;
  sequence_a seq_a;
  sequence_b seq_b;

  `uvm_declare_p_sequencer(virtual_sequencer)

  task body();
    // create sequence A
    // ...

    // start sequence A on appropriate sequencer
    fork
      seq_a.start(p_sequencer.seqr_a);
    join_none

    // wait until seq_a's item finishes
    // 'end_event' is built into uvm_transaction and is trigger
    // when the driver calls item_done()
    seq_a.seq_item_a.end_event.wait_trigger();

    // create sequence B based on seq_a.seq_item_a
    // ...

    // start sequence B
    fork
      seq_b.start(p_sequencer.seqr_b);
    join_none
  endtask
endclass

virtual_sequencer类包含两个总线序列发生器的句柄。我们通过让序列A执行一个项目然后启动序列B来实现同步。请注意,序列A在我们执行此操作时会运行,因为我们还没有将其杀死。您可以在此处实现任何类型的同步,例如抓取seqr_a以暂停序列A直到序列B的执行中的某个点等。要获得更多详细信息,请查看UVM用户指南。

如果您只想等到创建seq_a并将其seq_item_a随机化,您就必须在其中定义一个钩子事件:

class sequence_a extends uvm_sequence #(sequence_item_a);
  event item_randomized;

  task body();
    // create 'seq_item_a'
    // ...

    seq_item_a.randomize();
    -> item_randomized;
  endtask
endclass

在虚拟序列代码中,只需等待end_event,而不是等待item_randomized

您还可以在序列项目本身中创建item_randomized事件部分并从post_randomize()触发它:

class sequence_item_a extends uvm_sequence_item;
  event item_randomized;

  function post_randomize();
    -> item_randomized;
  endfunction
endclass

答案 1 :(得分:0)

执行此操作的正确方法是从序列体中删除randomize部分(如果可能)并在Tudor的答案中显示的seq.start方法之前将其随机化。

class virtual_seq extend uvm_sequence;
  sequence_a seq_a;
  sequence_b seq_b;

  `uvm_declare_p_sequencer(virtual_sequencer)

  task body();
    // create sequences
    // ...

     // randomize seq A
     seq_a.randomize();
     //randomize seq  B 
     seq_b.randomize() with {address = seq_A.address;} 
     // start sequences
     // ...

  endtask
endclass