UVM学习笔记(二)

电子说

1.3w人已加入

描述

第2章一个简单的UVM验证平台

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

2.3.1 加入transaction

引入transaction目的:

  • 更规范地传递信息, 更方便地引入transaction级的随机激励 。(一般来说,物理协议中的数据交换都是以帧或者包为单位的,而transaction就类似于这里包的概念)

my_transaction派生自uvm_sequence_item,而uvm_sequence_item是uvm_object的派生类。

派生自uvm_object的类 vs 派生自uvm_component的类

sequence

主要流程如下:

  • 在main_phase中,先使用randomize将tr随机化,之后通过drive_one_pkt任务将tr的内容驱动到DUT的端口上。在drive_one_pkt中,先将tr中所有的数据 压入队列data_q中 ,之后再 将data_q中所有的数据弹出并驱动 。将tr中的数据压入队列data_q中的过程相当于打包成一个byte流的过程。

2.3.2 加入env

引入uvm_env的原因:

  • 解决多个并列关系模块(driver、 monitor、 reference model和scoreboard等)实例化问题

问题:

  1. 在top_tb中例化这几个模块不行:run_test在top_tb结构层次之外建立一个新的结构层次,模块间传值需要通过config_db机制
  2. 在run_test中例化这几个模块不行:run_test函数本身限制,只能实例化一个模块。
  3. 在driver中例化其他模块不行:会让这些模块具备父子关系,打破了他们之间的并列关系。

解决:

  • 引入env机制,提供一个容器类,该容器类中包含了多个并列关系的模块,然后用run_test来实例化这个容器类

在UVM的树形结构中, build_phase的执行遵照从树根到树叶的顺序。

2.3.3 加入monitor

引入monitor原因:

  • 监测DUT的行为(可以检测输出,也可以检测输入)

monitor与driver的比较

sequence

关于monitor使用的4点注意:

  1. 所有的monitor类应该派生自uvm_monitor
  2. 与driver类似,在my_monitor中也需要有一个virtual my_if
  3. 使用uvm_component_utils宏注册
  4. monitor需要时刻收集数据,所以在main_phase中要使用**while(1)**循环

2.3.4 封装成agent

引入agent的原因:

  • driver和monitor二者 处理的是同一种协议 ,代码高度相似,所以将两者封装在一起。 不同的agent就代表了不同的协议

sequence

is_active是uvm_agent内置的一个成员变量,通过顶层传值,控制driver是否进行例化,且is_active的值默认为UVM_ACTIVE

  • UVM_PASSIVE:例化monitor而不需要例化driver(输出端口无需驱动)
  • UVM_ACTIVE:例化monitor,也需要例化driver(输入端口需要驱动)

例化动作可以在build_phase函数中完成,也可以在new函数中完成,但强烈建议仅在build_phase中完成实例化。

sequence

2.3.5 加入reference model

引入原因:

  • 完成和DUT相同的功能,作为DUT的参考模型

这里reference model对应的模块名为 my_model。my_model从i_agt得到my_transaction,并把my_transaction传递给my_scoreboard。在UVM中,通常使用 TLM( Transaction Level Modeling) 实现component之间transaction级别的通信。my_transaction在my_model中的传递方式大致分为三部分:

  1. 在my_monitor中使用uvm_analysis_port类例化一个用于发送transaction级数据的端口,并通过my_agent中uvm_analysis_port的引用变量往my_env传递端口
  2. 在my_model中使用uvm_blocking_get_port类例化一个用于接收transaction级数据的端口
  3. 在my_env中使用uvm_tlm_analysis_fifo类例化一个fifo。引入 connect_phase ,将fifo的analysis_export端口连接到i_agt.ap,fifo的blocking_get_export端口连接到mdl.port。(mdl为my_model类的例化对象)
  4. 使用fifo的原因: analysis_port是非阻塞性质的 , ap.write函数调用完成后马上返回,不会等待数据被接收。

2.3.6 加入scoreboard

引入scoreboard作用:

  • 比较reference model和o_agt的monitor的结果。

多进程的使用:

  • 在my_scoreboard中使用uvm_blocking_get_port新建两个port:exp_port、act_port,并在main_phase中,通过fork建立起两个进程,一个进程处理exp_port的数据(ref),当收到数据后,把数据放入expect_queue中;另外一个进程处理act_port的数据(dut),当收集到这些数据后,从expect_queue中弹出之前从exp_port收到的数据,并调用my_transaction的my_compare函数。
  • 由于DUT处理数据需要延时,而reference model是基于高级语言的处理,一般 不需要延时 ,因此 可以保证exp_port的数据在act_port的数据之前到来

2.3.7 加入field_automation机制

引入field_automation机制的原因:

  • 自动实现my_transaction中print、copy、compare这样的比较常见的结构体操作,简化my_transaction的实现。同时默认的pack_bytes(tr中的各个字段转换成byte流)和unpack_bytes(byte流转换成tr中的各个字段)也简化了driver、monitor的实现。

使用uvm_object_utils_beginuvm_object_utils_end来实现my_transaction的factory注册,在这两个宏中间,使用uvm_field宏注册所有字段。

`uvm_object_utils_begin(my_transaction)
      `uvm_field_int(dmac, UVM_ALL_ON)
      `uvm_field_int(smac, UVM_ALL_ON)
      `uvm_field_int(ether_type, UVM_ALL_ON)
      `uvm_field_array_int(pload, UVM_ALL_ON)
      `uvm_field_int(crc, UVM_ALL_ON)
   `uvm_object_utils_end
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分