UVM入门和进阶1:验证方法学概述_类库地图_工厂机制_覆盖方法
参考文档链接:https://verificationacademy.com/verification-methodology-reference/uvm/docs_1.2/html/
1 验证方法学概述
1.1 我们所处的验证时代
原有HDL受限于静态例化,同时随即约束短板
验证技术应该更为灵活化
Verilog1.0->Verilog2.0———>SystemVerilog3.0(基于verilog发展的所以一上来就是3.0)
1.2 UVM的优势
Universal(通用)
精力集中到:设计验证计划,减轻创建测试环境
1.3UVM的发展历程与演变
- UVM 1.0就是基于OVM
- UVM1.1 UVM1.2
- UVM1.2重大里程碑,被纳为标准
注意哪些是新方法,哪些是旧方法(一些旧方法已注销)
1.4 学习路线(共五周)
同v2SV一样,参考如何构建环境进行学习
五周学习不会超过50个类,非常核心的也就二十到三十个类之间大概十分之一,剩下的谁在用(UVM自动调用)
2 类库地图
2.1 概述
SV通过句柄一层一层的实现访问,UVM有替代
创建、访问、修改、配置都是可以重用的,所以反到类库当中
标准化减轻了构建验证环境的负担
SV与UVM对验证环境的共同需求
2.2 UVM世界(10大核心类)
对象的生成是动态的,需要UVM帮助去创建,如②提供对底层组建的创建与访问
环境中层次之间的创建,链接,层次间组建的控制方法
2.3 UVM世界讲解
核心基类:
① uvm_void与uvm_object(非常核心):会提空基本的方法,比如:拷贝、创建、打印
② 工厂类:注册、创建、覆盖我们的一些类型
③ 事务和序列类:发送激励,帮助实现测试场景。
事务类:组件之间数据类型的定义,数据是如何产生
④ 结构创建类:uvm_component(uvm组件类,重要,因为第五个所有的类型都继承于uvm_component。我们在UVM会经常提到这个类是继承于object还是component)
⑤ 环境组件类
⑥ 通信管道类:fifo , channel 与SV学到的队列和信箱类比
组件间相连用端口,发送数据的存储到通信管道内(因此第四周学通信管道和事务接口)
⑦ 消息报告类:消息如何打印,消息是怎么样控制的
⑧ 寄存器模型类(第五周学)
⑨ 线程同步类:与SVevent对比
⑩ 事务接口类(稍微特殊) :
有一些port后缀,代表端口,端口用来做通信的
这些端口是验证组件之间要通信的话他们之间往往需要端口,即⑩类与⑤类有关系,在组件之间例化,通过端口连接
⑩类还比较特殊再不继承于object而直接继承void
组件类、管道类、接口类的关系
3 工厂机制
3.1 概述:工厂机制是UVM的魅力所在,也是一种典型的设计模式(design pattern)
3.2 工厂的意义
3.2.1 替换、注册、配置
工厂为了:替换实例或注册过的类,为配置和覆盖(override)带来灵活性
覆盖:替换实例或类型。被替换的实例或类型应满足注册(registration)和多态(polymorphism)的要求
UVM验证环境两部分:
- 一部分构成了环境层次:通过uvm_component完成
- 一部分构成了环境属性(如配置):通过uvm_object完成
- uvm_component与uvm_object对比
3.2.2 注册
依赖于工厂创建对象
创建对象之前工厂需要模具/蓝图(类进行注册):SV的new与注册的区别在哪,因为有一个覆盖的好处
3.3 uvm_component与uvm_object
工厂我们一共就注册两大类型:uvm_component与uvm_object
验证不动产
- 性质:构成验证环境的
- 在uvm_component都有对应
非不动产
- 性质:帮助实现验证场景,在验证过程中动态产生
- transcation事务级传输对象数据包,这些类在UVM统一由uvm_object表示
3.3.2 uvm_{component, object}的例化
工厂提供的方式:
1 |
|
type_id是你注册到工厂里面的类型
1 |
|
creat与new
使用new或者create都能完成例化,但在UVM中我们用create,他是工厂提供的创建实例方式
3.3.4 工程提供的便利——创建分两步:①注册(registration)、②创建(create)
注册两个宏
`uvm_component_utils(comp_name);
`uvm_object_utils(obj_name);
三个步骤
- 定义:extends
- 注册:宏
- 构建:new
第一个例子(继承于component类)
泛式:形式不变,内容变
第一步:注册环节,第一个泛式
1 |
|
第二步:new函数,new函数参数是第二个泛式,参数不能添加新的参数也不能减少原有的参数
1 |
|
各个phase函数第二周学
第二个例子(继承于uvm_object类)
泛式:形式不变,内容变
第一步:注册环节,第一个泛式
1 |
|
第二步:new函数,new函数参数是第二个泛式
1 |
|
各个phase函数第二周学
3.3.5 工厂提供的便利
3.4 工厂机制:工厂类
不一定会出现在你的代码里面,但帮你规划了你的类
3.4.1 uvm_coreservice_t类
uvm_factory成员类:唯一并全局,负责注册、覆盖、例化
report_server成员类:唯一并全局,消息统筹和报告
tr_database成员类:全局,用于记录transaction记录
- get_root成员方法:返回UVM环境的结构顶层对象
uvm_coreservice_t,uvm_factory并不是uvm_component或uvm_object,没有例化在UVM环境结构中
目前学习的实例uvm_default_factory是已经存在的,不需要自己做例化
3.4.2 注册宏`uvm下划线{component, object}下划线utils
注册机制与create,以下自学:
3.4.3 注册后的对象创建(component或者object)
注意有无parent关系到是否可以看到UVM结构
创建后放置到类型库中
创建时,创建的类型如果没有被覆盖,则直接使用该类型的基础类型
3.5.6 componetn/object与工厂有关的方法(三类创建方法)
用object/component组件(uvm_component)去创建对象的方法:
- create()
- create_component()
- get()
- get_type_name()
- set_inst_override()
- set_type_override()
一旦创建,会把当前类型的图纸,放入到类型库里面
如果没有覆盖类型,则用工厂去创建
用工厂去创建也有很多方法:
使用typeid::创建
create_component_by_name()
- create_component_by_name()
- create_object_by_name()
- create_object_by_type()
我们只需要使用这些就可以了
4 覆盖方法
4.1 工厂提供的便利——覆盖(override)
4.1.1
从原来所属类型创建一个新的替换类型
- 无需修改原始代码,保持了原始代码封装性
- 新的替换类型必须与原有类型兼容
4.1.2 举例说明
你想要修改一个成型验证平台,你想修改driver
如果你修改driver很容易影响到别人,因此不能轻易修改代码
如果driver是VIP,内部代码不开放的
使用新的类型driver2替换driver
4.1.3 覆盖实现的要求
- 原有类型与新类型都需要注册
- 使用create()也就是工厂创建对象
- 新的替换类型必须与原有类型兼容
- 覆盖发生时,可以使用类型覆盖或实例覆盖
4.2 相关函数
4.2.1 set_type_override()//替换类型
- 函数原型
1 |
|
- 函数形参
1 |
|
- 调用方法
1 |
|
4.2.2 set_inst_override()//替换实例
- 函数原型
1 |
|
- 函数形参
1 |
|
- 调用方法
1 |
|
- 路径解释
1 |
|
句柄所代表的结构层级
4.3 如何使用覆盖相关的函数
不止一个类提供与覆盖有关的函数,然而名称与参数列表可能各不相同:
1 |
|
但我们推荐的就是使用typeid来调用set_{type, inst}_override
1 |
|
4.4 覆盖实例
定义例子comp1类
1 |
|
定义例子2comp2类
后面将1使用comp2替代comp1
进行覆盖
- c1通过new实例化的没有受到影响,没有经过工厂
- c2通过工厂create实例化的,因此成为了替换后的类型
如果没有comp1::type_id::set_type_override(comp2::get_type());
进行覆盖
则c1,c2指向的都是comp1类型对象
4.5 解释为什么comp2要继承comp1
例化时:
- 去找comp1的查找表
- 发现覆盖类型不为空,把comp1的类型替换为comp2的类型
能不能comp2与comp1没有继承关系:不能,你的override会有问题
因此,必须要有继承关系在
定义成员函数(除了new)能不能不用virtual:不能
例化时comp2仍然是父类comp1的句柄,调用方法则会调用父类的方法
4.6 确保正确覆盖的代码要求
4.7 parent wins
- 覆盖发生在例化之前,即
1 |
|
- 多次对同一对象override:谁的层次高听谁的(顶层test起作用了),即在配置过程中,谁层次高听谁的
4.8 总结:factory三要素:注册、创建和覆盖
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!