8 UVM序列2---sequencer&sequence、sequencer的层次化

目录​​​​​​​

1 sequencer和sequence

sequence和item的发送

发送序列的相关宏 

sequencer仲裁机制

Sequencer的锁定机制

2 sequence的层次化

Hierarchical Sequcence

Virtual Sequence

Layering Sequence


1 sequencer和sequence

sequence和item的发送

sequence挂载到sequencer上可以使用方法也可使用`uvm_do宏来实现,但根本的基础还是相应方法。先看用方法实现的实例,主要使用了两种方法:uvm_sequence::start和start_item()

class bus_trans etends uvm_sequence_item;
  rand int data;
  `uvm_object_utils_begin(bus_trans)
    `uvm_field_int(data,UVM_ALL_ON)
  `uvm_object_utils_end
    ...
endclass

class child-seq extends uvm_sequence;
  `uvm_object_utils(child_seq)
  ...
  task body();
    uvm_sequence_item tmp;
    bus_trans req;

    tmp = create_item(bus_trans::get_type(),m_sequencer,"req");
    `void($cast(req,tmp));
    strart_item(req);
    req.randomize with {data ==10};
    finish_item(req);
  ebdtask
endclass

class top_seq extends uvm_sequence;
  `uvm_object_utils(top_seq)
  ...
  task body();
    uvm_sequence_item tmp;
    child_seq cseq;
    bus_trans req;
    cseq = child_seq::typy_id::create("cseq");
    tem = create_item(bus_trans::get_type(),m_sequencer,"req");
    cseq.start(m_sequencer,this); //将sequence挂载到sequencer上
    `void($cast(req,tmp));
    start_item(req);
    req.randomize with {data==20};
    finish_item(req);
  endtask
endtask

方法一针对sequence挂载到相应sequencer中uvm_sequence::start(sequecer 句柄”,“上层sequence”,”优先级“,“指定pre_body()和post_body()执行次序”);。

使用技巧:m_sequencer是sequence中的成员变量,指向执行当前sequence的sequencer句柄;没有上层sequence则省略第2项参数。

例中在top_sequence中例化的cseq.start(m_sequencer,this)指明了第二项参数;在test中例化的seq对象就无需指定parent,seq.start(e.sqr);挂载之前记得例化sequence.

方法二针对item挂载到sequencer上的应用():

  • uvm_sequence::start_item(“item对象”,“优先级”,“指定item和其parent sequence挂载到的sequencer是否是一个,默认相同”)
  • uvm_sequence::finish_item(“item对象”,”优先级“)
  • item发送至driver的细节:

    创建item;
    通过start_item()方法等待获取sequencer的授权许可;
    得到授权后,执行parent sequence 的方法pre_do();
    对item进行随机化;
    通过finish_item()方法对item进行随机化处理后,执行parent sequence的 mid_do() 方法,以及调用uvm_sequencer::send_request()和uvm_sequencer::wait_for_item_done()来将item发送至driver在完成与diver之间的握手。
    最后执行parent sequence的post_do();

默认只传第一个参数,即需要传递的item对象。 

总结:对比start()和start_item/finish_item(),它们面向的挂载对象是不同的,但任何item的发送最终还是离不开seq挂载到sqr上。

发送序列的相关宏 

除了上述方法,常见的用来发送序列的宏如图所示。用户可以通过它来发送sequence和item,简化了代码,非常方便。但这些宏只能是由sequence调用,一般在body()中使用。

除此之外,还有传递优先级的`uvm_do_pri/`uvm_do_on_prio等

 如果使用宏来发送,上面代码可以简化为

class child_seq extends uvm_sequence;
  ...
  task body();
    bus_trans req;
    `uvm_create(req) //创建
    `uvm_rand_send_with (req,{data==10;})
  endtask

class top_seq extends uvm_sequence
  ..
  task body();
    child_seq cseq;
    bus_trans req;
    `uvm_do(cseq) //发送child_sequence
    `uvm_do_with(req,{data==20;}) //发送top_sqe中的item
  endtask
endclass

使用建议: 避免使用fork…join_any或fork…join_none来控制sequence的发送顺序,避免产生

                   sequence死锁的问题。 

sequencer仲裁机制

uvm_sequencer提供了uvm_sequencer::set_arbitration()函数设置仲裁模式,这种仲裁模式的值有以下几种选择:

UVM_SEQ_ARB_FIFO:默认模式。来自于sequences的发送请求,按照FIFO先进先出的方式被依次授权,和优先级没有关系。
UVM_SEQ_ARB_WEIGHTED:不同sequence的发送请求,将按照它们的优先级权重随机授权。
UVM_SEQ_ARB_RANDOM:不同的请求会被随机授权,而无视它们抵达顺序和优先级。
UVM_SEQ_ARB_STRICT_FIFO:不同的请求,会按照它们的优先级以及抵达顺序来依次授权,与优先级和抵达时间都有关系。
UVM_SEQ_ARB_STRICT_RANDOM:不同的请求,会按照它们的最高优先级随机授权,与抵达时间无关。
UVM_SEQ_ARB_USER:可以自定义仲裁方法user_priority_arbitration()来裁定哪个sequence的请求被优先授权。
 

Sequencer的锁定机制

uvm_sequencer提供了两种锁定机制:lock()和grab()

  • lock()/unlock():当sequencer按照仲裁机制授权给该sequence,一旦该sequence拿到授权,就不会将授权返回。只有当sequence执行unlock()时,才会释放这一锁定的权限;

  • grab()/ungrab():下一次授权周期就可以无条件地获取授权。也就是说,当已经有其他sequence获得授权时,grab()就无法获得授权。
     

2 sequence的层次化

Hierarchical Sequcence

可以包含sequence和item,对它们进行协调和控制,自身也会挂载到sequencer上(同一个sqr)

Virtual Sequence

与hierarchial sequence 最大的区别就是,它能将内部不同的sequence挂载到不同的sequencer上.

除此之外还有以下特性:

  • virtual sequence 中包含了各个子模块的sequence。
  • 在virtual sequence中是通过使用宏`uvm_declare_p_sequencer(),声明了一个virtual sequencer的句柄,通过p_sequencer可以进一步访 问virtual sequencer内部各个子sequencer 句柄。
  • virtual sequencer中有各个子环境的sequencer句柄,本身并不会发送item,只承担路由作用
  • 在顶层环境例化virtual sequencer并且将内部各个sequencer的句柄与底层sequencer句柄连接,避免句柄悬空。
  • 在顶层test中将virtual sequence 挂载到virtual sequencer上。

 注意:在使用`uvm_declare_p_sequencer()时,宏在后台完成了两步操作:1声明了一个virtual sequencer句柄p_sequencer;2'void($cast(p_sequncer,m_sequencer))

(`uvm_declare_p_sequencer()详解)

Layering Sequence

待续。。

相关参考文档:

【1】sequence和sequencer — UVM

【2】Sequence的层次化

【3】UVM学习笔记--sequence和sequencer

【4】虚序列器与虚序列(virtual sequencer与virtual sequence)


版权声明:本文为m0_59670134原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。