专栏首页摸鱼范式【UVM COOKBOOK】配置test环境

【UVM COOKBOOK】配置test环境

不想错过我的推送,记得右上角-查看公众号-设为星标,摘下星星送给我

欢迎大家加入2022届数字IC交流群,QQ群号 1060380138

PDF获取

后台回复COOKBOOK,即可获取PDF笔记以及原版COOKBOOK

后台回复即可获取

配置test环境

Testbench配置

概述

介绍

设计可重用testbench的关键原则之一是使其尽可能可配。这就意味着testbench及其组成部分可以很容易地重用和快速修改(即重新配置)。在testbench中,有任意数量的值通常可以写成文本值,如for循环次数、字符串名称、随机权重、其他约束表达式值和coverage bin值。这些值可以用SystemVerilog变量表示,可以在运行时设置(和更改),也可以用SystemVerilog参数表示,但必须在elaboration时设置。由于它们提供的灵活性,应始终在可能的情况下构建存放这些属性的配置对象并使用 uvm_config_db API 访问。

另一方面,像总线宽度这样的,必须在细化时确定,因此就不能通过动态配置对象实现。有许多关于在UVM中处理静态参数的文章:

  • 参数化test文章说明如何对UVM工厂使用参数化测试。
  • Parameters Package一文展示了如何集中在HDL/DUT和HVL/TB域之间共享的参数。
  • 参数和重用一文展示了如何通过uvm_component层次结构向下传递大量参数。

配置对象

配置对象是组织配置变量的一种有效的、可重用的方法。在一个典型的testbench中,通常会有几个配置对象,每个对象都绑定到一个组件。配置对象被创建为uvm_object的子类,以封装testbench层次结构的给定分支的所有相关配置变量。也可能有一个单独的、附加的配置对象来保存全局配置变量。配置对象中的每个配置变量都可以声明为rand,因此配置对象可以被随机化。

UVM配置数据库可以有效地处理用户定义的配置对象的范围和存储。下面是典型agent配置对象的代码。它具有指向driver和monitor与agent关联的BFM接口的虚接口,以及描述和控制这些BFM的许多变量。

// configuration class 
class wb_config extends uvm_object; 
 `uvm_object_utils( wb_config ); 
// Configuration Parameters 
 virtual wb_m_bus_driver_bfm wb_drv_bfm; // virtual driver BFM
 virtual wb bus monitor bfm  wb mon bfm; // virtual monitor BFM 

 int m_wb_id;                 // Wishbone bus ID 
 int m wb master id;          // Wishbone bus master id for wishone agent
 int m mac id;                // id of MAC WB master

 int unsigned m_mac_wb_base_addr;  // Wishbone base address of MAC 
    bit [47:0]  m_mac_eth_addr;       // Ethernet address of MAC 
    bit [47:0]  m_tb_eth_addr;        // Ethernet address of testbench for sends/receives

 int m mem slave size;       // Size of slave memory in bytes
 int unsigned m_s_mem_wb_base_addr; // base address of wb memory for MAC frame buffers 
 int m_mem_slave_wb_id;  // Wishbone ID of slave memory
 int m_wb_verbosity;  // verbosity level for wishbone messages 
    
 function new( string name = "" ); 
  super.new( name ); 
 endfunction 
endclass

使用配置对象

任何使用配置对象的组件都应该执行以下步骤:

  • 如果配置对象句柄为空(即尚未在外部设置),则检索其配置。
  • 创建其内部结构并基于配置定义其行为
  • 配置其子组件

test组件作为顶层组件,从test参数package或UVM配置数据库(例如虚接口句柄)获取配置值。然后为环境中的组件设置特定于test的配置变量。

class test_mac_simple_duplex extends uvm_test; 
 ... 
 wb_config wb_config_0; // config object for WISHBONE BUS
 function void set_wishbone_config_params(); 
// set configuration info 
// NOTE  The MAC is WISHBONE slave 0, mem_slave_0 is WISHBONE slave 1 
// MAC is WISHBONE master 0, wb_master is WISHBONE master 1 
  wb_config_0 = new(); 
        if (!uvm_config_db #(virtual wb_m_bus_driver_bfm)::get(this, "", "WB_DRV_BFM", wb_config_0.wb_drv_bfm)) 
   `uvm_fatal(...) 
  if (!uvm_config_db #(virtual wb_bus_monitor_bfm)::get(this, "", "WB_MON_BFM", wb_config_0.wb_mon_bfm))
   `uvm_fatal(...) 
  wb_config_0.m_wb_id = 0; // WISHBONE 0
  wb_config_0.m_mac_id = 0;  // the ID of the MAC master
  wb_config_0.m_mac_eth_addr = 48'h000BC0D0EF00; 
  wb_config_0.m_mac_wb_base_addr = 32'h00100000; 
  wb_config_0.m_wb_master_id = 1; // the ID of the wb master
  wb_config_0.m_tb_eth_addr = 48'h000203040506; 
  wb_config_0.m_s_mem_wb_base_addr = 32'h00000000; 
  wb_config_0.m_mem_slave_size = 32'h00100000; // 1 Mbyte
  wb_config_0.m_mem_slave_wb_id = 0; // the ID of slave mem
  wb_config_0.m_wb_verbosity = 350; 
  uvm_config_db #(wb_config)::set(this, "*", "wb_config", wb_config_0); 
 endfunction 
 ... 
 function void build_phase(uvm_phase); 
  set_wishbone_config_params(); 
  ... 
 endfunction 
 ... 
endclass

注意,如果在UVM配置数据库中没有找到虚接口,则使用`uvm_fatal()。这将立即停止test,并将给定的消息传递给`uvm_fatal()调用。可以选择将这些`uvm_fatal()消息转换为`uvm_error()消息,以便在停止之前使testbench运行更久。

要么直接将配置对象传递给使用配置对象的组件,要么使用uvm_config_db::get获取配置对象。在本例中,driver从配置对象获取虚接口句柄、ID和详细信息。注意BFM不是uvm_components。因此,driver和/或monitor代理可能还需要通过函数调用将相关的配置数据传递给BFM。一次函数调用通常足以一次传递所有数据,从而最小化调用开销。

class wb_m_bus_driver extends uvm_driver #(wb_txn, wb_txn); 
 ... 
 local virtual wb_m_bus_driver_bfm m_bfm; // Virtual Interface
 wb_config m_cfg; 
 function void build_phase( uvm_phase phase ); 
  if (m_config == null) 
   if( !uvm_config_db #( wb_config )::get( this , "" , "wb_config" , m_cfg ) )    begin 
    `uvm_fatal(...) 
   end 
  m_bfm = m_cfg.wb_drv_bfm; // set local virtual if property
  ... 
 endfunction 
 function void connect_phase( uvm_phase phase ); 
  super.connect_phase( phase ); 
  m_bfm.set_m_id(m_config.m_wb_master_id); //Set config value in BFM
 endfunction 
 function void end_of_elaboration(); 
  set_report_verbosity_level_hier(m_config.m_wb_wb_verbosity); 
 endfunction 
 ... 
endclass 

配置sequence

下文有关于配置sequence的单独章节。

配置DUT连接

建立HDL-to-Testbench连接始终是一种必需的配置活动。SystemVerilog模块(通常是HDL端顶层模块,有时是更精细的模块封装级别)必须将虚接口添加到配置空间中。在HVL Testbench端,test组件从UVM配置数据库中检索相关的虚接口句柄,并将它们应用到适当的配置对象中:

class test_mac_simple_duplex extends uvm_test; 
 ... 
 function void set_wishbone_config_params(); 
  wb_config_0 = new(); 
// Get the virtual interface handle that was set in the top module or protocol module 
  if (!uvm_config_db #(virtual wb_m_bus_driver_bfm)::get(this, "", "WB_DRV_BFM", wb_config_0.wb_drv_bfm)) 
   `uvm_fatal(...) 
  if (!uvm_config_db #(virtual wb_bus_monitor_bfm)::get(this, "", "WB_MON_BFM", wb_config_0.wb_mon_bfm)) 
   `uvm_fatal(...) 
  ... 
  uvm_config_db #( wb_config )::set(this , "*", "wb_config", wb_config_0, 0); // put in config
 endfunction 
 ... 
endclass

配置sequence

一个可配置的sequence

配置sequence最通用的方法是默认使用其完整的层次名称,但允许根据需要设置任何其他名称:

class my_bus_seq extends uvm_sequence #( my_bus_sequence_item ); 
 string scope_name = ""; 
 task body(); 
  my_bus_config m_config; 
  if( scope_name == "" ) begin 
  scope_name = get_full_name(); // this is {sequencer.get_full_name() , get_name() } 
  end 
  if( !uvm_config_db #( my_bus_config )::get( null , scope_name , "my_bus_config" , m_config ) ) begin 
   `uvm_error(...) 
  end 
 endtask 
endclass

考虑一个名为“initialization_sequence”的sequence运行在sequencer“uvm_test_top.env.sub_env.agent1.sequencer”上。上面代码中的scope_name默认设置为"uvm_test_top.env.sub_env.agent1.sequencer.initialization_sequence"。

sequence配置最常见的用例是为agent及其组成组件(sequencer、driver、monitor……)获取agent的配置对象集。

class sub_env extends uvm_env; 
 ... 
 function void build_phase( uvm_phase phase ); 
  ... 
  my_bus_config agent1_config; 
  ... 
  uvm_config_db #( my_bus_config )::set( this , "agent1*" , "my_bus_config" , agent1_config ); 
  ... 
 endfunction 
 task main_phase( uvm_phase phase ); 
  my_bus_sequence seq = my_bus_sequence::type_id::create("my_bus_sequence"); 
  seq.start( agent1.sequencer ); 
 endtask 
 ... 
endclass 

使用sub_env作为context,可配置sequence中的set()调用和默认get()调用将匹配并致使sequence能够访问agent的配置对象。

每个sequence配置

上面可配置sequence类的缺省完整层次作用域名称可以用来唯一地标识多个sequence实例,从而使它们服从不同的单独配置,而所需要的只是sequence的给定实例名不同。

例如,环境类可能像这样:

class sub_env extends uvm_env; 
 ... 
 function void build_phase( uvm_phase phase ); 
  ... 
  my_bus_config agent1_config, agent1_error_config; 
  ... 
  agent1_config.enable_error_injection = 0; 
  agent1_error_config.enable_error_injection = 10; 
// most sequences do not enable error injection 
  uvm_config_db #( my_bus_config )::set( this , "agent1*" , "my_bus_config" , agent1_config ); 
// sequences with "error" in their name will enable error injection 
  uvm_config_db #( my_bus_config )::set( this , "agent1.sequencer.error*" , "my_bus_config" , agent1_error_config ); 
  ... 
 endfunction 
 task main_phase( uvm_phase phase ); 
  my_bus_sequence normal_seq = my_bus_sequence::type_id::create("normal_seq"); 
  my_bus_sequence error_seq = my_bus_sequence::type_id::create("error_seq"); 
  normal_seq.start( agent1.sequencer ); 
        error_seq.start( agent1.sequencer ); 
 endtask 
 ... 
endclass 

由于可配置sequence类使用给定的sequence名执行config_db get()调用,正常sequence将选择禁用错误注入的配置对象,而error_sequence将选择error配置对象。

完全忽略组件层次结构

也可以完全忽略sequence配置的组件层次结构。这样做的好处是,实际上可以定义仅用于配置sequence的行为作用域,并使这些行为作用域与组件层次结构完全分离。上面描述的可配置sequence在这个场景中也可以使用。

例如,在virtual sequence 中:

class my_virtual_sequence extends uvm_sequence #( uvm_sequence_item_base ); 
 ... 
 task body(); 
  my_bus_sequence normal_seq = my_bus_sequence::type_id::create("normal_seq"); 
  my_bus_sequence error_seq = my_bus_sequence::type_id::create("error_seq"); 
  normal_seq.scope_name = "sequences::my_bus_config.no_error_injection"; 
  error_seq.scope_name = "sequences::my_bus_config.enable_error_injection"; 
  normal_seq.start( agent1.sequencer ); 
  error_seq.start( agent1.sequencer ); 
 endtask 
 ... 
endclass 

这种增加灵活性的使用模型缺点是,testbench上的每个sequence和组件必须就命名方案达成一致,或者至少能够处理这种任意命名方案。由于不再保证作用域名称的唯一性,当从模块级转换到集成级testbench时,可能会面临一些重用挑战。

使用Parameter Package

当参数化DUT或接口时,参数值几乎总是在testbench上使用。由于这个原因,我们不应该用实例声明的直接文本值特定化这些公共参数。而是在一个Package中定义相应的命名参数和相关的值,由环境的HDL/DUT端和testbench端共享。这极大地帮助我们避免了这样的错误,即参数值在一边发生了改变,而在另一边却没有发生改变,或者test配置参数是DUT参数的某个函数,而在进行改变时可能会导致计算错误。

请注意,此“共享package”不必是放置所有test参数的地方。不适用和被DUT使用的test参数可以直接在test中特定化。共享参数package应仅包含在 HDL/DUT 和 HVL/TB 域之间共享的参数。

参数package的使用示例

下面的WISHBONE示例涉及两个WISHBONE总线设备、从机存储器和一个以太网MAC(媒体访问控制器)。参数被放在一个包test_params_pkg中,并在实例化HDL顶层模块中的WISHBONE设备和testbench端的test类中使用。

// MAC WISHBONE parameters 
 parameter mac m wb id = 0;        // WISHBONE bus master id of MAC
 parameter mac_slave_wb_id = 1;    // WISHBONE bus slave id of MAC

endpackage

下面展示了在HDL top模块中使用参数mem_slave_size和mem_slave_wb_id实例化WISHBONE总线从机内存模块。注意,在top_mac_hdl模块中导入了test_params_pkg:

module hdl_top_mac; 
 ... 
 import test_params_pkg::*; 
// WISHBONE interface instance 
// Supports up to 8 masters and up to 8 slaves 
 wishbone_master_bfm  wb_mstr_bfm(wb_bus_if); 
 wishbone_bus_syscon_if wb_bus_if(); 
//----------------------------------- 
// WISHBONE 0, slave 0: 000000 - 0fffff 
// this is 1 Mbytes of memory 
wb_slave_mem #(mem_slave_size) wb_s_0 ( 
// inputs 
.clk ( wb_bus_if.clk ), 
.rst ( wb_bus_if.rst ), 
.adr ( wb_bus_if.s_addr ), 
.din ( wb_bus_if.s_wdata ), 
.cyc ( wb_bus_if.s_cyc ), 
.stb ( wb_bus_if.s_stb[mem_slave_wb_id]  ), 
.sel ( wb_bus_if.s_sel[3:0] ), 
.we ( wb_bus_if.s_we ), 
// outputs 
.dout( wb_bus_if.s_rdata[mem_slave_wb_id] ), 
.ack ( wb_bus_if.s_ack[mem_slave_wb_id]  ), 
.err ( wb_bus_if.s_err[mem_slave_wb_id]  ), 
.rty ( wb_bus_if.s_rty[mem_slave_wb_id]  ) 
); 
 ... 
endmodule 

testbench的test类中用于设置WISHBONE总线从机内存配置对象值的参数使用如下所示。注意,不是使用数字字面值32'h00100000,而是使用包含命名DUT参数mem_slave_size的表达式来赋值地址值。

package tests_pkg; 
 ...
 import test_params_pkg::*; 
 ... 
 `include "test_mac_simple_duplex.svh" 
endpackage 
//----------------------------------------------------------------- 
class test_mac_simple_duplex extends uvm_test; 
 ... 
 wb_config wb_config_0; // config object for WISHBONE BUS
 ... 
 function void set_wishbone_config_params(); 
//set configuration info 
 wb_config_0 = new(); 
 wb_config_0.m_s_mem_wb_base_addr = mem_slave_wb_id * slave_addr_space_sz; // base address of slave mem
 wb_config_0.m_mem_slave_size = 2**(mem_slave_size+2); // defaultis 1 Mbyte 
 wb_config_0.m_mem_slave_wb_id = mem_slave_wb_id; // WISHBONE bus slave id of slave mem 
 ... 
 endfunction 
 ... 
endclass 

多个实例

在参数集有多个实例的情况下,可以使用基于实例助记符的命名约定来区分实例,或者使用基于参数化类的方法来通过参数特定化区分参数集。

注意,现在存在两个Wishbone从机mem实例。每个都有自己的特定化参数。这是通过指定参数及其默认值的参数化类来处理的。然后,通过使用typedef创建特定化的参数化类,为每个实例设置实际的参数值。

package test_params_pkg; 
 import uvm_pkg::*; 
// WISHBONE general slave parameters 
 parameter slave_addr_space_sz = 32'h00100000; 
// WISHBONE slave memory parameters 
 class WISHBONE_SLAVE #(int mem_slave_size = 18, int mem_slave_wb_id = 0); 
 endclass 
// Specializations for each slave memory instance 
 typedef WISHBONE_SLAVE #(18, 0) WISHBONE_SLAVE_0; 
 typedef WISHBONE SLAVE #(18, 1) WISHBONE SLAVE 1;
// MAC WISHBONE parameters
 parameter mac m wb id = 0;     // WISHBONE bus master id of MAC
 parameter mac_slave_wb_id = 2; // WISHBONE bus slave id of MAC
endpackage

要在上述代码中使用特定化 WISHBONE_SLAVE_0 或 WISHBONE_SLAVE_1 的参数 mem_slave_size 和 mem_slave_wb_id,请使用以下语法:name_of_specialization::parameter_name,如下图所示。

module hdl_top_mac; 
 ... 
 import test_params_pkg::*; 
// WISHBONE interface instance 
// Supports up to 8 masters and up to 8 slaves 
 wishbone_master_bfm wb_mstr_bfm(wb_bus_if); 
 wishbone_bus_syscon_if wb_bus_if(); 
//----------------------------------- 
// WISHBONE 0, slave 0: 000000 - 0fffff 
// this is 1 Mbytes of memory 
wb_slave_mem #(WISHBONE_SLAVE_0::mem_slave_size) wb_s_0 ( 
// inputs 
.clk ( wb_bus_if.clk ), 
.rst ( wb_bus_if.rst ), 
.adr ( wb_bus_if.s_addr ), 
.din ( wb_bus_if.s_wdata ), 
.cyc ( wb_bus_if.s_cyc ), 
.stb ( wb_bus_if.s_stb [WISHBONE_SLAVE_0::mem_slave_wb_id] ), 
.sel ( wb_bus_if.s_sel[3:0] ), 
.we ( wb_bus_if.s_we ), 
// outputs 
.dout( wb_bus_if.s_rdata[WISHBONE_SLAVE_0::mem_slave_wb_id] ), 
.ack ( wb_bus_if.s_ack [WISHBONE_SLAVE_0::mem_slave_wb_id] ), 
.err ( wb_bus_if.s_err [WISHBONE_SLAVE_0::mem_slave_wb_id] ), 
.rty ( wb_bus_if.s_rty [WISHBONE_SLAVE_0::mem_slave_wb_id] ) 
); 
 ... 
endmodule 

从sequence中访问配置资源

sequence通常需要访问testbench资源,如寄存器模型或配置对象。这最好使用uvm_config_db来检索资源,作为被其他sequence扩展的sequence基类的body()方法的第一个操作。

uvm_config_db可以通过几种方式访问资源:

  • 使用m_sequencer句柄访问资源
// Resource access using m_sequencer: 
spi_env_config m_cfg; 
task body(); 
 if(!uvm_config_db #(spi_env_config)::get(m_sequencer, "", "spi_env_config", m_cfg))  begin 
  `uvm_error("BODY", "spi_env_config config_db lookup failed") 
 end 
endtask: body 
  • 使用sequence的get_full_name()调用访问资源
// Resource access using get_full_name(): 
spi_env_config m_cfg; 
task body(); 
 if(!uvm_config_db #(spi_env_config)::get(null, get_full_name(), "spi_env_config", m_cfg)) begin 
  `uvm_error("BODY", "spi_env_config config_db lookup failed") 
 end 
endtask: body 
  • 当资源未绑定到组件层次结构时,使用作用域字符串访问资源
// Resource access using pre-assigned lookup: 
spi_env_config m_cfg; 
task body(); 
 if(!uvm_config_db #(spi_env_config)::get(null, "SPI_ENV::", "spi_env_config", m_cfg)) 
    begin 
 `uvm_error("BODY", "spi_env_config config_db lookup failed") 
 end 
endtask: body

前两个方法基本上是等价的,因为它们都是基于testbench层次结构中的m_sequencer位置或testbench层次结构中的sequence "伪"位置创建作用域字符串。这两种方法之间的细微差别如下。对于第一个方法,m_sequencer.get_full_name()在m_sequencer作为参数传递给get()调用时被调用,生成testbench层次结构中该sequencer的路径。一个例子是“uvm_test_top.env.my_agent.sequencer”。对于第二个方法,get_full_name()是在sequence上调用的,而不是在sequencer上。如果sequence是在sequencer上启动的(即 m_sequencer 句柄不为空),则此 get_full_name() 调用返回sequencer的路径,并附加sequence名称。这方面的一个例子可能是“uvm_test_top.env.my_agent.sequencer.my_seq”。这对于针对在特定sequencer上运行的特定sequence的特定配置信息很有用。

第三种方法依赖于用户商定的不同配置域的命名约定,该约定可以在特定的项目或工作组中很好地工作,但可能由于名称冲突而导致重用问题。

base sequence实现的完整示例如下所示。派生sequence必须调用base sequence body()方法,以确保在启动激励程序之前设置了资源句柄。

// 
// Sequence that needs to access a testbench resource via the configuration space 
// 
// Note that this is a base class; any class extending it must call super.body() 
// at the start of its body task to get set up 
// 
class register_base_seq extends uvm_sequence #(bus_seq_item); 
 `uvm_object_utils(register_base_seq) 
// Handle for the actual sequencer to be used: 
    bus_sequencer BUS; 
// Handle for the environment configuration object: 
 bus_env_config env_cfg; 
// Handle for the register model 
 dut_reg_model RM; 
 function new(string name = "register_base_seq"); 
  super.new(name); 
 endfunction 
 task body; 
// Get the env configuration object - using get_full_name() 
  if(!uvm_config_db #(bus_env_config)::get(null, get_full_name(), "bus_config", env_cfg)) begin 
   `uvm_error("BODY", "Failed to find bus_env_config in the config_db")
  end 
// Assign a pointer to the register model which is inside the env config object: 
  RM = env_cfg.register_model; 
 endtask: body 
endclass: register_base_seq 
// 
// A derived sequence: 
// 
class initialization_seq extends register_base_seq; 
 `uvm_object_utils(initialization_seq) 
 task body; 
  super.body(); // assign the resource handles
  ... // Sequence body code 
    endtask: body 
endclass: initialization_seq 

使用此技术的另一个示例是访问配置对象中的虚接口以等待硬件事件。

宏 成本-效益 分析

宏在减少小的类似模式的代码段的重复键入、隐藏来自不同供应商的仿真器之间的实现差异或限制、或使关键代码段更不容易出错以便重用等方面都很有用。UVM中的许多宏满足这些条件,但并非全部。虽然宏的好处通常是显而易见且直接的,但与其使用相关的成本通常是不透明的,并且在以后的代码更改变得越来越突发性时可能会出现问题。

在DVCon 2011的一篇题为OVM-UVM Macros-Costs vs Benefits的论文中,对宏的使用进行了详细的探讨。

  • 它会检查一些宏导致的隐藏成本,包括代码膨胀、低性能和调试困难。
  • 它确定哪些宏提供了良好的成本效益权衡,哪些没有。
  • 它展示了如何用简单的SystemVerilog代码替换高成本的宏。

这些建议摘要如下:

关于这篇论文的更多内容可以参考 https://verificationacademy.com/resource/6646

END

本文分享自微信公众号 - 摸鱼范式(icparadigm),作者:Key1h

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-08-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【UVM COOKBOOK】什么是UVM COOKBOOK/内附PDF获取

    UVM COOKBOOK是由mentor工程师编写的,UVM进阶书籍,帮助用户更好地使用UVM,提高验证环境的运行效率以及可移植性。

    空白的贝塔
  • 【UVM COOKBOOK】UVM基础【二】

    testbench分析部分的第一个任务是监测DUT上的活动。和driver一样,monitor也是agent的组成部分。类似于driver组件,执行的也是实际信...

    空白的贝塔
  • 基于UVM的UART验证环境

    今天偶然在群里看到有人分享了Mentor Graphics提供的一个UART的UVM验证环境代码,包含了UVM的基本使用以及进阶的UVM寄存器模型。这里也分享给...

    空白的贝塔
  • 【UVM COOKBOOK】DUT-Testbench Connections

    UVM testbench对象不能直接连接到DUT信号来驱动或采样。driver和monitor组件对象与DUT之间的连接是通过一个或多个具有静态信号端口的BF...

    空白的贝塔
  • 【UVM COOKBOOK】Testbench Architecture【一】

    UVM testbench 是使用SystemVerilog(动态)类对象与SystemVerilog(静态)接口和结构化层次结构中的模块交互构建的。层次结构...

    空白的贝塔
  • 【UVM COOKBOOK】Testbench Architecture【二】

    考虑构建一个用于验证SPI主机DUT的testbench作为模块级testbench的一个例子。在这种情况下,UVM环境有两个agent—APB agent在其...

    空白的贝塔
  • 【UVM COOKBOOK】Sequences||UVM Sequences

    UVM sequence在事务层面提供了一种面向对象的激励生成方法,一方面让测试用例编写更加高效,另一方面提高了测试用例的可复用性。

    空白的贝塔
  • 动静结合,了解典型的UVM验证平台架构

    典型的基于UVM 的验证平台(Testbench)通常会实例化DUT和UVM Testcase,以及完成DUT和UVM Testcase之间的链接。其中Test...

    AsicWonder
  • 概述UVM中的build、configure和connect

    在UVM testbench开始发送激励之前,必须构建其组件层次结构以及验证组件之间的连接关系。

    AsicWonder
  • 【UVM COOKBOOK】Sequences||sequence item与事务方法

    UVM产生激励是通过sequence sequencer以及driver三者配合实现的。生成激励的flow的框架是围绕sequence构建的,但是生成数据流使用...

    空白的贝塔
  • UVM学习--基本概念篇1

    UVM 是 Universal Verification Methodology 的缩写,即通用验证方法学。它起源于 OVM(Open Verification...

    数字IC小站
  • 便携式激励vs形式化vsUVM验证方法在IP块的整个生命周期中的比较分析

    验证技术和方法不断发展,以应对日益严峻的验证挑战。当今行业的最新技术是基于UVM和基于形式化(Formal)的验证流程。事实证明,这两种技术都可以显著提高验证质...

    空白的贝塔
  • 第六节,Springboot多环境(dev、test、prod)配置

    项目开发中,我们往往需要根据不同环境修改配置文件,springboot提供了一套完美的解决方案

    DencyCheng
  • 揭开UVM configure机制的神秘面纱

    UVM中的configure机制用来将一些对象(objects)和数据(data)传递到验证平台中的各种组件。

    AsicWonder
  • 如何在Chef中使用角色和环境来控制服务器配置

    在构建基础架构时,管理多服务器,服务,用户和应用程序可能会很快变得很难。配置管理系统可用于帮助您管理这种混乱。

    丰一川
  • 【仿真技巧】 0:00 VCS+VERDI+reverse=败者食尘!!

    假设一种场景,在调试环境的时候,运行到15min的时候,环境出现bug,需要去debug。也许错误的第一现场并不是15min的时候,可能在14min30s-15...

    空白的贝塔
  • 【日更计划117】数字IC基础题【UVM部分】

    如果由于超出最大时间的某些错误而导致测试无法进行,那么仿真超时机制有助于停止仿真。在UVM中,set_global_timeout(timeout)是一个便捷函...

    空白的贝塔
  • 创建您的第一本Chef Cookbook

    Cookbook是Chef框架的关键组成部分之一,其描述了相关节点的所需状态,并允许Chef推送需达到该状态的更改数据。由于需要进行配置的选项和区域数量众多,第...

    PantaZheng
  • SystemVerilog和UVM到底是啥关系?

    UVM提供了丰富的基类库和验证方法学,并且被主流的EDA工具、IP供应商和设计公司采用。现在,使用SystemVerilog基本上等同于使用UVM验证。

    AsicWonder

扫码关注云+社区

领取腾讯云代金券