UVM基础⼊门(⼀)
UVM 基础⼊门
⼀、框架
Kitty大众健身操集锦
框架⼀
构成环境的组件都从uvm_component类继承⽽来,这是因为它们都从uvm_component类继承了pha机制,都会经历各个pha阶段。常见组件如下:
uvm_quencer:所有的quencer都要派⽣⾃uvm_quencer。
quencer功能:组织管理quence,driver申请数据时,它就把quence⽣成的quence_item发给driver。
uvm_driver:所有的driver都要派⽣⾃uvm_driver。
driver功能:向quencer申请quence_item(数据包),并将包⾥的信息按照总线协议规定驱动到DUT的端⼝上。
//uvm_driver定义
class uvm_driver #(type REQ=uvm_quence_item,type RSP=REQ) extends uvm_component;
uvm_monitor:所有的的monitor都要派⽣⾃uvm_monitor。
monitor功能:为了检测接⼝数据,从DUT接收数据,并将其转成transaction级别的quence_item,发送给
scoreboard,供其⽐较。
uvm_agent:所有的agent要派⽣⾃uvm_agent。
agent功能:将quencer、driver和monitor封装在⼀起,agent模块的使⽤提⾼了代码的可重⽤性。
(UVM_ACTIVE/UVM_PASSIVE、两种模式)
uvm_scoreboard:⼀般的scoreboard都要派⽣⾃uvm_scoreboard。
scoreboard功能:⽐较reference model和monitor分别发送来的数据,根据⽐较结果判断DUT是否正确⼯作。
uvm_env:所有的env要派⽣⾃uvm_env。个人信息表
怎样看住房风水 env功能:将平台上的component组件封装在⼀起,实现⼀个环境多个⽤例。运⾏不同⽤例时,在其中实例化env即可。可以看做⼀个结构化的容器。
uvm_test:所有的测试⽤例要派⽣⾃uvm_test或其派⽣类。
任何⼀个派⽣的测试⽤例中,都要实例化env。这样,当⽤例运⾏时,才能把数据发给DUT,并接收DUT的数据。
reference model:UVM中并没有针对reference model定义⼀个类。通常,reference model直接派⽣⾃uvm_component。
作⽤就是模仿DUT,完成与DUT相同的功能。DUT是⽤Verilog写成的时序电路,⽽reference model则可以直接使⽤SystemVerilog⾼级语⾔的特性,同时还可以通过DPI等接⼝调⽤其他语⾔来完成与DUT相同的功能。
框架⼆
框架三
⼆、各组建关系
component与object是UVM中最基本的两个概念。
uvm_object是UVM中最基本的类,⼏乎全部的类都是由uvm_object类派⽣出来,其中包含uvm_component。
uvm_object 提供的核⼼⽅法主要提供与数据操作的相关服务,Copy、Clone、Compara、Print、pack/unpack
uvm_component有两⼤特性是uvm_object所不具备的。
**⼀是通过在new的时候必须要指定parent参数来产⽣⼀种树形的组织结构;
⼆是具有pha的⾃动执⾏特点。所有的UVM树的结点都是由uvm_component构成的,只有基于uvm_component派⽣出的类才有可能是UVM树的结点。UVM中⼀些常见类的继承关系如图3所⽰。
三、uvm_object类
类的预定义
预定义uvm_object的相关扩展类,以便在uvm_object的相关⽅法中调⽤:
typedef class uvm_report_object;
typedef class uvm_object_wrapper;
typedef class uvm_objection;// uvm_object类中未使⽤
typedef class uvm_component;// uvm_object类中未使⽤
含含糊糊typedef class uvm_status_container;
类的⽅法
类的声明
virtual class uvm_object extends uvm_void;
endclass
变量声明
// 静态变量,决定是否使能UVM中的播种机制,影响全局的reed()⽅法;
static bit u_uvm_eding = 1;
// 局部变量,通过new函数将类的实例化名传递给该变量,变量对⼦类及外部不可见;
local string m_leaf_name;
// 局部变量,使⽤new()函数实例化类时,m_inst_count⾃动加1并传递给该局部变量,⽤于返回实例化id,变量对⼦类及外部不可见; local int m_inst_id;
// 静态局部变量,⽤于返回实例化次数,该局部变量对⼦类可见,对外部不可见;
static protected int m_inst_count;
static uvm_status_container __m_uvm_status_container = new;
// 查找表,⽤于copy()函数的实现;
local static uvm_object uvm_global_copy_map[uvm_object];
⽅法声明
virtual function void copy(uvm_object rhs);// **默认进⾏深复制**
//相⽐于copy函数,print(), compare(), pack()等函数需要对数据操作做出额外的配置,声明如下:
virtual function void print(uvm_printer printer=null);
virtual function void sprint(uvm_printer printer=null);
virtual function bit compare(uvm_object rhs, uvm_comparer comparer=null);
virtual function int pack(ref bit bitstream[], input uvm_packer packer=null);
virtual function int unpack(ref bit bitstream[], input uvm_packer packer=null);
//其他见UVM参考⼿册
⽅法的实现
new()函数:通过给定的字符串名称创造该类的实例化对象,如果名字没有给定,那么该对象⽆名。字符串名传递给局部变量m_leaf_name,实例化 m_inst_id 通过静态局部变量m_inst_count计数的⽅式指定。
function uvm_object::new (string name="");
m_inst_id = m_inst_count++;
m_leaf_name = name;
endfunction
clone ()函数:虚⽅法,创建并返回待clone对象的副本。
function uvm_object uvm_object::clone();
uvm_object tmp;
反射星云
tmp = ate(get_name());// 调⽤create()⽅法,创建实例
if(tmp == null)
uvm_report_warning("CRFLD", $sformatf("The create method failed for %s, object cannot be cloned",get_name()), UVM_NONE);
el
return(tmp);
endfunction
print ()函数:⽅法以给定的 printer 参数控制的格式和⽅式深度打印该对象的属性。如果参数没有指定,那么使⽤全局的<uvm_default_printer>所定义的输出格式。
function void uvm_object::print(uvm_printer printer=null);
老师生日if(printer==null)// 检查是否给定uvm_printer参数,c如果没有指定参数,使⽤默认的uvm_default_printer;
printer = uvm_default_printer;
if(printer == null)// 检查uvm_default_printer是否为空;
`uvm_error("NULLPRINTER","uvm_default_printer is null")
// 其中d=UVM_STDOUT=1
$fwrite(d,sprint(printer));// 使⽤$fwrite调⽤sprint函数将类对象的属性打印⾄标准输出。
丧葬endfunction ```
sprint ()函数: 与 print() 函数类似,但 sprint() 函数返回字符串⽽不是显⽰到标准输出。因此该函数被print()函数调⽤。
⾮虚函数,不可被重载,继承⼦类必须重写do_print()函数,并且使⽤提供的printer策略来格式化输出。
function string uvm_object::sprint(uvm_printer printer=null);
bit p;
if(printer==null)
printer = uvm_default_printer;// 同样的,调⽤该⽅法时如果没有指定参数,那么使⽤默认的uvm_default_printer;
// not at top-level, must be recursing into sub-object
统战部工作if(!printer.istop()) begin
__m_uvm_status_container.printer = printer;
__m_uvm_field_automation(null, UVM_PRINT,"");
do_print(printer);
return"";
end