《UVM实战卷Ⅰ》学习笔记 第二章 一个简单的UVM验证平台(2)

写在前面:为了避免文章过长,引起阅读疲劳,会将有些章节分开写

目录

2.3 为验证平台加入各个组件

1.什么是基于信号级的操作?什么是基于transaction的操作?

2.uvm_compoent和uvm_object的区别在哪里?

3.关于drive_one_pkt的实现

4.为什么要引入env?

5.factory机制带来的不一样的例化方式

6.引入env带来的变化

7.初识monitor

8.初识agent

9.在new和build_phase或者其他phase中完成例化有什么不同呢?

10.初识TLM通信

11.初识field_automation


2.3 为验证平台加入各个组件

1.什么是基于信号级的操作?什么是基于transaction的操作?

transaction是个抽象的概念,我们可以结合代码来理解,先看不同driver中什么是信号级再看什么是transaction.需求是:满足一般物理协议,以帧或者包传递数据.解决是:引入transaction

信号级

task my_driver::main_phase(uvm_phase phase);
   phase.raise_objection(this);
   `uvm_info("my_driver", "main_phase is called", UVM_LOW);
   vif.data <= 8'b0; 
   vif.valid <= 1'b0;
   while(!vif.rst_n)
      @(posedge vif.clk);
   for(int i = 0; i < 256; i++)begin
      @(posedge vif.clk);
      vif.data <= $urandom_range(0, 255);
      vif.valid <= 1'b1;
      `uvm_info("my_driver", "data is drived", UVM_LOW);
   end
   @(posedge vif.clk);
   vif.valid <= 1'b0;
   phase.drop_objection(this);
endtask
//可以看到信号驱动等式的左右两边,一边是信号(也就是我们定义的成员变量),一边是具体的value

transaction级

task my_driver::main_phase(uvm_phase phase);
   my_transaction tr;
   phase.raise_objection(this);
   vif.data <= 8'b0;
   vif.valid <= 1'b0;
   while(!vif.rst_n)
      @(posedge vif.clk);
   for(int i = 0; i < 2; i++) begin 
      tr = new("tr");
      assert(tr.randomize() with {pload.size == 200;});
      drive_one_pkt(tr);
   end
   repeat(5) @(posedge vif.clk);
   phase.drop_objection(this);
endtask
//这里例化transaction,然后驱动

其中注意一点transaction extends uvm_sequence_item,只有从uvm_sequence_item继承才可以使用sequence机制.

2.uvm_compoent和uvm_object的区别在哪里?

区别在于生命周期,也就是是否一直存在.uvm_compoent(比如my_driver)一直存在,而uvm_object(比如my_transaction)完成数据流之后就会结束

3.关于drive_one_pkt的实现

如果这部分读起来有困难,可以参考任意一门编程语言数据类型部分中的队列,看一下其内建函数,应该就可以理解.

4.为什么要引入env?

目前我们的验证环境中只有一个driver,基本验证常识告诉我们这是远远不够的.现在driver是在tb中通过run_test进行例化(多说一句,如果面向对象编程语言基础薄弱,最好补充一下),所以现在的需求是:后续的组件需要有空间例化.基于:run_test只能例化一个/需要构建一个UVM的空间(不能像最初driver在tb中那样例化)/在driver中例化更不方便,提出的解决是:寻找一个容器.

这是套娃模式的开始,在功能上讲driver和其他组件是在一个层面上的,但是它现在却独占了run_test这个例化机会,这是不合理的,是一种资源浪费,因此让driver后退一步,和其他组件一起在容器中例化,而容器去run_test中开启例化.这样也就形成了UVM独立的层次结构.

我们给这个容器起名:env

5.factory机制带来的不一样的例化方式

drv = my_driver::type_id::create("drv", this);

6.引入env带来的变化

①run_test的主角发生了变化,成了env.②在tb中使用config_db的set想drv传递接口,其中第二个参数也就是实例名发生了变化,此时env成了uvm_test_top,而driver依路径索引成了uvm_test_top.drv.参考书中图2-3

7.初识monitor

需求是:基于验证常识,检测dut输入输出端口,解决是:引入monitor,收集dut端口信号,转换成transaction发送至验证环境的其他部件

8.初识agent

把前边第四个点提的套娃模式继续,完成之后,UVM层次参考书中图2-6.相比上次套娃,这次tb中只需变路径就好了,env顶层在run_test中.

9.在new和build_phase或者其他phase中完成例化有什么不同呢?

首先确定哪个phase,如书中所讲,在main_phase便会报错,只能在build_phase.那么new和phase的区别呢?我之前有一篇文章谈的是这个从《UVM实战卷Ⅰ》第2章组件的添加过程中的实际需求谈phase机制的核心意义_IC-V的博客-CSDN博客

10.初识TLM通信

前文一直在提基于transaction通信,那么具体是怎么实现的呢?既然是通信,那就从两个角度来实现接收和发送.需求是:完成数据在组件间的传递,解决是:引入TLM通信.和之前一样,关于TLM后续有更为详细的讲解在第4章.

这里找到了一个既接又发的部件ref_mod,从monitor接,发到scoreboard.主要讲了ref_mod和monitor之间的通信,后边才会加入scoreboard.fifo那里可以理解为一个管道,将mon和ref连接起来.

11.初识field_automation

需求是:避免自行在transaction定义各种函数,解决是:引入field_automation,实现自动化

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值