学习目标
UVM入门和进阶部分1
学习内容
1.全面认识验证方法学:
认识UVM世界的版图(类库)和核心机制
学习核心的UVM组件和层次构建方式
了解常见的UVM组件的通信方式
深入UVM测试场景的构成
UVM的寄存器模型应用
2.验证环境的共同需求:
组件的创建和访问
环境的结构创建、组件之间的连接和运行
不同阶段的顺序安排
激励的生成、传递和控制
测试的报告机制
3.UVM类库地图
①核心基类
②工厂类
③事务和序列类
④结构创建类
⑤环境组件类
⑥通信管道类
⑦信息报告类
⑧寄存器模型类
⑨线程同步类
⑩事务接口类
4.每一个uvm_{component,object}在例化的时候都应该给予一个名字(string)
“full name”指的是component所处的完整层次结构
创建uvm_component对象时:
comp_type::type_id::create(string name,uvm_component parent);
创建uvm_object对象时:
object_type::type_id::create(string name);
//工厂提供的便利---创建(create)
class comp1 extends uvm_component;
'uvm_component_utils(comp1) //注册*
//new函数的参数也是范式,注释的*表示范式
function new(string name="comp1",uvm_component parent=null); //parent就是上一层
super.new(name,parent); //继承
$display($sformatf("%s is created",name));
endfunction:new
function void build_phase(uvm_phase phase); //先没讲
super.build_phase(phase);
endfunction:build_phase
endclass
class obj1 extend uvm_object; //定义
'uvm_object_utils(comp1) //注册*
function new(string name="obj1"); //构建,一个参数
super.new(name);
$display($sformatf("%s is created",name));
endfunction :new
endclass
comp1 c1,c2;
obj1 o1,o2;
initial begin
//SV创建对象
c1=new("c1");
o1=new("o1");
//UVM用工厂创建对象
c2=comp1::type_id::create("c2",null);
//注册类型;第一个冒号找到工厂图纸类型,第二个冒号调用create函数
o2=obj1::type_id::create("o2");
end
5.运用factory的步骤:
将类注册到工厂
在例化前设置覆盖对象和类型(可选)
对象创建
6.uvm_coreservice_t类,该类内置了uvm世界核心的组件和方法,主要包括:
唯一的uvm_factory,该组件用来注册、覆盖和例化
全局的report_server,该组件用来做消息统筹和报告
全局的tr_database,该组件用来记录transaction记录
get_root()方法用来返回当前uvm环境的结构顶层对象
7.uvm_coreservice_t不是component或者object类型,也并没有例化在uvm环境中,而是独立于uvm环境之外的
8.利用工厂创建对象的方法:
create_component_by_name()
create_component_by_type()
create_object_by_name()
create_object_by_type()
9.uvm_component/object提供的创建方法:
create()
create_component()
get()
get_type_name()
set_inst_override()
set_type_override()
10.要想实现覆盖特性,原有类型和新类型均需要注册
覆盖的新类型使用继承,是子类
11.覆盖发生时,可以使用“类型覆盖”或者“实例覆盖”
类型覆盖:uvm层次结构下的所有原有类型都被覆盖类型所替换
实例覆盖:在某些位置中的原有类型会被覆盖类型所替换
12.set_inst_override()是一个静态函数
static function void set_inst_override(uvm_object_wrapper override_type,string inst_path,uvm_component parent=null);
string inst_path指向的是组件结构的路径字符串
uvm_component parent=null
如果缺省,表示inst_path为绝对路径,否则使用{parent.get_full_name().inst_path}作为目标路径
orig_type::type_id::set_inst_override(new_type::get_type(),“orig_inst_path”)
13.set_type_override()是一个静态函数
static function void set_type_override(uvm_object_wrapper override_type,bit replace=1);
uvm_object_wrapper override_type为某一个类在工厂注册时的句柄
bit replace=1,有覆盖存在,新覆盖会替代旧覆盖,否则,有覆盖存在,该覆盖不会生效
orig_type::type_id::set_type_override(new_type::get_type())
14.其他的一些使用覆盖相关的函数
uvm_component::set_{type,inst}_override{by_type}
uvm_component_registry::set{type,inst}override
uvm_object_registry::set{type,inst}override
uvm_factory::set{type,inst}_override
15.覆盖实例
module factory_override;
import uvm_pkg::*;
'include "uvm_macros.svh"
class comp1 extends uvm_component;
'uvm_component_utils(copm1)
function new(string name="comp1",uvm_component parent=null);
super.new(name,parent);
$display($sformatf("comp1::%s is created",name));
endfunction:new
virtual function void hello(string name);
$display($sformatf("comp1::%s is said hello!",name));
endfunction
endclass
class comp2 extends comp1;
'uvm_component_utils(copm2)
function new(string name="comp2",uvm_component parent=null);
super.new(name,parent);
$display($sformatf("comp2::%s is created",name));
endfunction:new
function void hello(string name);
$display($sformatf("comp2::%s is said hello!",name));
endfunction
endclass
comp1 c1,c2;
initial begin
comp1::type_id::set_type_override(comp2::get_type());
c1=new("c1");
c2=comp1::type_id::create("c2",null);
c1.hello("c1");
c2.hello("c2");
end
endmodule
结果:
comp1::c1 is created
comp1::c2 is created
comp2::c2 is created
comp1::c1 is said hello!
comp2::c2 is said hello!
要素:
新旧类型都要注册
新类型是继承的子类
父类用virtual
factory的覆盖机制只会影响factory注册并且创建的对象
先做覆盖,再做类型对象创建
高层次的覆盖优先级更高