当前位置:   article > 正文

UVM_COOKBOOK学习【DUT-Testbench Connections】

uvm cookbook

关注微信公众号摸鱼范式,后台回复COOKBOOK获取COOKBOOK原本和译本 PDF度盘链接

将testbench连接到DUT

概述

本节,我们主要讨论将UVM testbench连接到RTL DUT的问题。

UVM testbench对象不能直接连接到DUT信号来驱动或采样。driver和monitor组件对象与DUT之间的连接是通过一个或多个具有静态信号端口的BFM组件间接实现的。这些BFM组件以module或interface的形式实现,为了完成到UVM monitor或driver组件类的连接,我们使用虚接口句柄来引用静态接口的内容。

UVM方法学使用uvm_config_db将一个虚接口句柄从静态testbench模块传递给UVM对象类。在使用虚接口实现BFM一节中可以找到两个相关示例。

概述显示了如何通过 uvm_config_db 中的虚接口句柄在monitor和driver中引用 hdl_top 中的具体 BFM 接口。

在书中的大多数示例中,我们都使用“Dual Top”方法。这意味着DUT和BFM实例化在一个静态模块层次结构,顶部通常称为“hdl_top”,而部分testbench负责启动UVM test是在一个单独的模块中,称为“hvl_top”。这种分离在有独立的团队负责项目的设计和验证方面时很有帮助,在转向testbench加速时也很有帮助,因为此时hdl_top的内容将是可合成的。

我们还讨论使用一个abstract-concrete class pair从class对象连接到静态BFM的另一种方法。这种方法使用多态性和类句柄通过API与BFM通信。

最后,我们讨论了DUT-TB连接中参数的处理,其中参数用于指定协议接口中信号的位宽。

Interfaces and Virtual Interfaces

SystemVerilog Interfaces

SystemVerilog接口提供了一种方便的方法,可以将相关信号组织到容器中,以简化模块之间的连接。一个接口可以包含:

  • 端口声明
  • 信号和变量声明
  • 除了模块实例外的任何SystemVerilog代码
  • Modport
  • 其他interface

接口的声明可以带有端口,也可以不带有端口。如果它是用端口声明的,那么当接口实例化时,这些端口需要被赋值给信号。

所有声明为接口端口或接口内部的信号都可以通过一个接口实例在模块之间传递。一个模块可以有接口端口,并且可以将这些端口与其他类型的信号端口混合。接口内的信号可以被引用,也可以使用接口内的层次引用来赋值,例如,interface_name.signal_name。

接口可以包括除模块实例之外的任何SystemVerilog代码。这意味着它们可以包含initial块、任务、函数、SystemVerilog断言(SVA)、covergroup和类,这些对于构造验证组件来说都是有用的。

SystemVerilog接口也可以包含modports,它允许根据使用视角组织接口信号的方向。例如,一个总线主机总是驱动一个地址和strobe信号,而一个总线从机总是接收这些信号。虽然从方法论的角度来看,这似乎是一个好想法,但围绕着modport构造的语言有笨拙的元素,在实践中并不是特别有用。

Virtual Interface

在SystemVerilog中,如果类没有在定义信号的模块或接口范围内声明,类就不能对信号进行引用。对于开发可重用的testbench来说,这是非常严格的。

但是,类可以通过虚接口句柄引用接口中的信号。这就允许类在接口内为信号赋值或采样信号的值,或者在接口内调用任务或函数。

为了从类中引用接口,它必须声明为虚接口:

  1. class protocol_driver extends uvm_driver #(protocol_seq_item);
  2. virtual protocol_interface vif;
  3. // Virtual interface declaration
  4. ....
  5. task run_phase(uvm_phase phase);
  6. @(posedge vif.clock);
  7. // Accessing the clock signal via the virtual interface handle
  8. vif.send_packet(....);
  9. // Calling a BFM method via the virtual interface handle

如果虚接口没有被赋值,其为默认值null,并且类访问它内部的任何尝试都会在仿真器中导致一个空指针异常。要使虚接口句柄有效,必须将testbench模块部分中的具体静态接口实例赋值给它。在SystemVerilog中有多种方法可以完成这个工作,但对于UVM,推荐的、最可扩展的方法是使用uvm_config_db。

UVM配置数据库(uvm_config_db)

uvm_config_db

uvm_config_db是一个UVM实用类,用于在UVM testbench上的组件对象之间传递配置对象。任何对uvm_config_db的调用都是用存储或检索的数据对象的类型参数化的。要在uvm_config_db中存储对象,使用它的set()方法;而要从uvm_config_db中检索对象,则使用它的get()方法。这两个方法都有赋值对象的参数;将对象与查找键关联;并定义UVM testbench层次结构中的哪些组件可以引用该对象。

还是之前说过的,这里的 ‘’定义UVM testbench层次结构中的哪些组件可以引用该对象‘’ ,实质上只是域名划分上的定义,并不是根据调用位置所处组件的类型来做相应确认的。第一章中我有提到过。

有关uvm_config_db的一般使用的更多信息,请参见下文。

使用uvm_config_db连接UVM testbench到DUT

要将基于testbench (hdl_top)的静态模块的虚接口句柄传递给UVM组件,请使用uvm_config_db,如下所示:

步骤1:在测试台的HDL部分,将静态接口赋值给uvm_config_db中的虚接口:

  1. sfr_if SFR_IF();
  2. // Declaration of SFR interface – This will be connected to modules
  3. initial begin
  4. uvm_config_db #(virtual sfr_if)::set(null, “uvm_test_top”, “SFR”, SFR_IF);
  5. end

请注意以下几点:

  • uvm_config_db是用virtual sfr_if类型参数化的
  • set()方法的第一个参数是context,它是一个UVM组件对象句柄;在本例中,由于我们是在testbench的HDL部分,所以是一个null对象句柄。
  • set()方法的第二个参数是一个字符串,用于标识可能访问数据对象的UVM testbench组件层次结构中的UVM组件实例名。这里使用“uvm_test_top”来限定只接受顶级UVM test对象的访问。它可以被分配一个通配符,比如“*”,这意味着UVM测试台上的所有组件都可以访问它,但这可能没什么帮助,而且在get()过程中可能会有查找开销。

前面说过的,第一个参数(组件对象实例名)和第二个参数用‘’.‘’拼接共同作为get函数两个参数拼接需要匹配的字符串。也只是表面上解释为限定可访问的组件

  • set()方法的第三个参数是一个字符串,用作查找名,属于get方需要匹配上的‘’钥匙‘’
  • set()的最后一个参数是赋值给在uvm_config_db中创建的虚接口句柄的静态接口。

步骤2:在UVM test组件中,将uvm_config_db条目中的虚接口句柄赋值给配置对象中的虚接口句柄:

  1. // Virtual interface handle declared inside an agent configuration object
  2. class sfr_config extends uvm_object;
  3. ...
  4. virtual sfr_if sfr_vif;
  5. ...
  6. endclass
  7. class test extends uvm_test;
  8. ...
  9. function void build_phase(uvm_phase phase);
  10. sfr_config cfg = sfr_config::type_id::create("cfg");
  11. // Assigning the SFR virtual interface handle via the uvm_config_db #(...)::get() method
  12. if(!uvm_config_db #(virtual sfr_if)::get(this, "", "SFR", cfg.sfr_vif)) begin
  13. `uvm_error("VIF_GET", "Unable to find the SFR virtual interface in the uvm_config_db", UVM_LOW)
  14. end

请注意以下几点:

  • uvm_config_db::get()方法是一个函数,它返回一个单bit值来指示对象检索是否成功;这将用于检查,以确保在查找失败时testbench不会继续运行。
  • uvm_config_db::get()方法使用虚接口类型进行参数化,以便从数据库检索正确的对象类型。
  • get()方法的第一个参数是context,传递的是进行调用的UVM组件的句柄——this
  • 第二个参数instance_name传递了一个空字符串" ",这意味着仅根据组件的路径字符串用于标识访问数据对象的UVM testbench组件层次结构(即" uvm_test_top ")。
  • 第三个参数是uvm_config_db查找字符串,它应该与在HDL模块中的查找字符串相匹配,在本例中是“SFR”。
  • 第四个参数是虚接口句柄。在本例中,句柄位于将被传递给agent的uvm_config_object中。

UVM cookbook的内容排布有些问题,致使一些内容会反复出现,如config_db机制

如果你正在重用一个验证组件,那么你只需要知道它的接口名称以及如何将它指定给UVM验证组件配置

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/603051
推荐阅读
相关标签
  

闽ICP备14008679号