story · 2021年07月26日

UVM sequence分层的几种体现

验证环境需要对数据进行分层。例如,将32比特的寄存器读写封装成数据读写和状态读写等实际业务操作等或者对底层sequence进行一些随机控制等。实现这种分层可以有两种方式:

1、Sequence layer,在sequencer内部(sequence)中进行分层,无需分别创建 high-layer sequencer和 low-layer sequencer。

2、Virtual sequence,在sequencer外部进行分层,例如使用virtual sequencer。

实际项目中,一般两种分层的手段都会采用。对于一个底层的数据项lower_env_items定义如下:

class lower_env_item extends uvm_sequence_item;
  rand bit[‘dATA_SIZE-1:0] payload[];
  rand int pl_size;
  constraint c_pload ( pl_size < `MAX_PL;
    payload.size() == pl_size; )    ... // Constructor and OVM automation macros go here,
endclass : lower_env_item

底层的seuquence能够将 lower_env_item数据项驱动给DUT

class lower_env_base_seq extends uvm_sequence #(lower_env_item);
  ... // Constructor and `uvm_sequence_utils macro
  virtual task body();
    …  endtask : body
endclass : lower_env_base_seq

这时候如果我们有了更high level的数据项upper_env_item驱动需求,该数据项是包含多个lower_env_item的数组:

class upper_env_item extends uvm_sequence_item;
  rand int unsigned max_item_size; // maximum pl_size of lower item
  rand int unsigned num_items; // maximum number of lower items
  rand lower_env_item item[]; // array of lower items
  constraint c_itein { num_items == item.size();
    num_items inside { [1:10]}; }
    constraint c_item_size ( max_item_size inside {[10:20]}; }
    ... // Constructor and UVM automation macros go here,
  function void post_randomize();
    foreach(item[i]) begin
    item[i] = lower_env_item::type_id::create{$psprintf("item[%0d]", i))    ;
    assert(item[i].randomize with {pl_size <= max_item_size; }))
    else `uvm_error ("RNDFML", "item randomization failed")
  end
 endclass : upper_env_item

在这种请求下可以使用第一种分层方式,在high-layer sequence中依然使用low-layer sequencer进行驱动,同时对low-layer sequence进行更加精细化的控制。

1.png

class upper_env_item_seq extends uvm_sequence #(lower_env_item);
  ... // Constructor and UVM automation macros
  upper_env_item u_item; // Contains an array of lower_env_items
  task body();
    // Create a upper-level item.
    `uvm_create(u_item)
    ...// Randomize it here with appropriate constraints.
    for(int i = 0 ; i< u_item.num_items; i++)
      `uvm_send(u_item.item[i])
  endtask : body
endclass: upper_env_item_seq

在上面的例子中,我们随机生成了包含多个lower_env_item的数组upper_env_item_seq,然后分别进行发送。

同样一个例子,我们也可以使用多个sequencer(high-layer sequencer和low-layer sequencer),如下图所示。

2.png

每一个sequence都有一个对应的sequencer。在实际中使用一个sequencer可以完成的事情肯定不会再创建另外一个sequencer,因为sequencer属于静态的UVM组件,属于平台型的内容,不可能每一个用例都需要创建一个sequencer。

这里的例外就是virtual sequencer,因为某些high-layer sequence需要协调多个low-layer sequencer进行工作,无法仅使用一个单一的sequencer进行驱动。

作者:XinXinHu
原文链接:https://mp.weixin.qq.com/s/5qUwkaZo9hNd5kJZ-ZF71w
微信公众号:
数字芯片.jpg
授权转自数字芯片实验室公众号,请勿二次转载。

推荐阅读

更多数字IC设计技术干货等请关注数字芯片实验室专栏。
推荐阅读
关注数
12315
内容数
220
前瞻性的眼光,和持之以恒的学习~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息