UVM糖果爱好者教程 - 5.验证环境

本文将介绍其他的验证组件。

Subscribers

功能覆盖率收集器(jelly_bean_fc_sucbscriber)将生成的 jelly beans视为计数器。从monitor发送的jelly_bean_transaction通过21行上的write函数的sample方法进行采样,并对 jelly beans的风味,颜色和其他特征的交叉覆盖。

class jelly_bean_fc_subscriber extends uvm_subscriber#(jelly_bean_transaction);
   `uvm_component_utils(jelly_bean_fc_subscriber)
 
   jelly_bean_transaction jb_tx;
 
   covergroup jelly_bean_cg;
      flavor_cp:     coverpoint jb_tx.flavor;
      color_cp:      coverpoint jb_tx.color;
      sugar_free_cp: coverpoint jb_tx.sugar_free;
      sour_cp:       coverpoint jb_tx.sour;
      cross flavor_cp, color_cp, sugar_free_cp, sour_cp;
   endgroup: jelly_bean_cg
 
   function new(string name, uvm_component parent);
      super.new(name, parent);
      jelly_bean_cg = new;
   endfunction: new
 
   function void write(jelly_bean_transaction t);
      jb_tx = t;
      jelly_bean_cg.sample();
   endfunction: write
endclass: jelly_bean_fc_subscriber

Scoreboard

在功能覆盖用户中,jelly_bean_transaction在write函数中被采样。与功能覆盖率收集器类似,关注write功能是关键。记分板subscriber使用write函数调用父组件(jelly_bean_scoreboard)中的check_jelly_bean_taste函数。此check_jelly_bean_taste函数将DUT响应与预期响应进行比较。

typedef class jelly_bean_scoreboard;
 
class jelly_bean_sb_subscriber extends uvm_subscriber#(jelly_bean_transaction);
   `uvm_component_utils(jelly_bean_sb_subscriber)
 
   function new(string name, uvm_component parent);
      super.new(name, parent);
   endfunction: new
 
   function void write(jelly_bean_transaction t);
      jelly_bean_scoreboard jb_sb;
 
      $cast( jb_sb, m_parent );
      jb_sb.check_jelly_bean_taste(t);
   endfunction: write
endclass: jelly_bean_sb_subscriber

check_jelly_bean_taste函数期望DUT模块“对酸味巧克力味jelly_bean产生不利反应,同时对其他组合产生积极反应。”当DUT正确响应时,将打印jelly_bean风味和颜色。当DUT工作不正常时,该功能将打印出错信息。

class jelly_bean_scoreboard extends uvm_scoreboard;
   `uvm_component_utils(jelly_bean_scoreboard)
 
   uvm_analysis_export#(jelly_bean_transaction) jb_analysis_export;
   local jelly_bean_sb_subscriber jb_sb_sub;
 
   function new(string name, uvm_component parent);
      super.new(name, parent);
   endfunction: new
 
   function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      jb_analysis_export = new( .name("jb_analysis_export"), .parent(this));
      jb_sb_sub = jelly_bean_sb_subscriber::type_id::create(.name("jb_sb_sub"), .parent(this));
   endfunction: build_phase
 
   function void connect_phase(uvm_phase phase);
      super.connect_phase(phase);
      jb_analysis_export.connect(jb_sb_sub.analysis_export);
   endfunction: connect_phase
 
   virtual function void check_jelly_bean_taste(jelly_bean_transaction jb_tx);
      uvm_table_printer p = new;
      if (jb_tx.flavor == jelly_bean_transaction::CHOCOLATE && jb_tx.sour) begin
         if (jb_tx.taste == jelly_bean_transaction::YUCKY) begin
            `uvm_info("jelly_bean_scoreboard",
                       { "You have a good sense of taste.\n", jb_tx.sprint(p) }, UVM_LOW);
         end else begin
            `uvm_error("jelly_bean_scoreboard",
                        { "You lost sense of taste!\n", jb_tx.sprint(p) });
         end
      end else begin
         if (jb_tx.taste == jelly_bean_transaction::YUMMY) begin
            `uvm_info("jelly_bean_scoreboard",
                       { "You have a good sense of taste.\n", jb_tx.sprint(p) }, UVM_LOW);
         end else begin
            `uvm_error("jelly_bean_scoreboard",
                        { "You lost sense of taste!\n", jb_tx.sprint(p) });
         end
      end
   endfunction: check_jelly_bean_taste
endclass: jelly_bean_scoreboard

许多人认为创建一个单独的记分板是一件麻烦事。在我们的例子中,检查jelly_bean_sb_subscriber中的预期响应可能更直接,因为预期的响应是从内部创建的。然而,有时候需要两个分析端口,一个用于预期数据,另一个用于实际数据。subscriber的写入功能不支持多个analysis port。解决这个问题的一个办法是开发一个有两个subscriber的记分板。考虑到未来的可扩展性,创建像记分板这样的两层结构可能是一个好主意。

Environment

为了提供结论,本节将解释包含所有验证组件的验证环境。简单地说,环境连接了之前解释的agent和subscriber。看一下专栏的第一篇文章将有助于更好地理解这一概念。

class jelly_bean_env extends uvm_env;
   `uvm_component_utils(jelly_bean_env)
 
   jelly_bean_agent         jb_agent;
   jelly_bean_fc_subscriber jb_fc_sub;
   jelly_bean_scoreboard    jb_sb;
 
   function new(string name, uvm_component parent);
      super.new(name, parent);
   endfunction: new
 
   function void build_phase(uvm_phase phase);
      super.build_phase(phase);
      jb_agent  = jelly_bean_agent::type_id::create(.name("jb_agent"), .parent(this));
      jb_fc_sub = jelly_bean_fc_subscriber::type_id::create(.name("jb_fc_sub"), .parent(this));
      jb_sb     = jelly_bean_scoreboard::type_id::create(.name("jb_sb"), .parent(this));
    endfunction: build_phase
 
   function void connect_phase(uvm_phase phase);
      super.connect_phase(phase);
      jb_agent.jb_ap.connect(jb_fc_sub.analysis_export);
      jb_agent.jb_ap.connect(jb_sb.jb_analysis_export);
   endfunction: connect_phase
endclass: jelly_bean_env

下一篇文章将展示使用这些组件的预期测试。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值