文章目录
1.验证方法学概述
1.1验证情况概述
- 验证结构的复用和代码的复用很难;
- 原有HDL缺乏随机约束和功能覆盖率;
- EDA公司开发出平台限定性语言 Specman/e和Vera;
1.2 SV
- 从2002年的SV3.0标准逐步发展成为IEEE-1800 SV2017标准;
- SV的核心是面向对象、随机约束、线程通信、功能覆盖率收集等;
1.3 UVM
- UVM1.0在2011年发布,目前用的是UVM1.2;
- UVM在eRM、AVM、OVM的基础上发展的;
- 所有验证方法学的目的都在于提供一些可重用的类,减轻项目之间水平复用和垂直复用的工作量;
- UVM提供了一套可靠的验证框架;面向所有的数字设计,从模块级到芯片级、从ASIC到FPGA;
- UVM自定义的框架构建类和测试类能够帮助验证人员减轻环境构建的负担,将更多的精力集中在制订验证计划和创建测试场景;
2 类库地图
2.1类库地图概述
- 在SV中,验证环境整体的构建是从底层模块的验证组件搭建到通信和测试激励生成;这些元素无论是软件对象的创建、访问、修改、配置,还是组件之间的通信等都是通过用户自定义的方式来实现的;
- UVM将验证过程中可以重用和标准化的部分都规定在其方法学的类库中,通过标准化的方式减轻构建环境的负担;
- 验证环境的共同需求是:1、组件的创建和访问 2、环境的结构创建、组件之间的连接和运行 3、不同阶段的顺序安排 4、激励的生成、传递和控制 5、测试的报告机制;
- 在组件通信中,UVM提供了功能丰富的TLM(transaction level model)接口,从而保证相邻组件的通信不再通过显式句柄引用,而是独立于组件的通信方式;
- 对于测试序列sequence的生成和传输也是利用TLM传输在sequence和driver之间完成;
- UVM的报告机制可以将来自于不同组件、不同级别的信息并且加以过滤,最终生成测试报告;
2.2 UVM核心类(10个)
2.3 UVM类库地图
3 工厂机制
3.1工厂机制是软件的一种典型设计模式;
3.2工厂机制意义
- factory存在的目的是更方便地替换验证环境中的实例或者注册了的类型,同时工厂的注册机制也带来了配置的灵活性;实例或者类型替换,在UVM中称作覆盖(override);
- UVM验证环境由两部分构成,一部分是uvm_component类,构成了环境的层次,另一部分是uvm_object类,构成了环境的属性和数据传输;(uvm_component继承自uvm_object);
- factory的目的是用来创建对象,在创建对象之前要先进行类型注册;
- 工厂注册的类型有两种,一个是uvm_component,另一个是uvm_object;
3.3 uvm_component和uvm_object
-
factory三个步骤:定义、注册、创建;
-
创建uvm_component
//创建uvm_component
class comp1 extends uvm_component;//定义
`uvm_component_utils(comp1) //注册
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
- 创建uvm_object
//创建uvm_object
class obj1 extends uvm_object;
`uvm_object_utils(obj1)
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);
o2 = obj1 ::type_id::create(o2);
end
- 上面代码的结果
/*
创建的结果
c1 is created
o1 is created
c2 is created
obj1 is created
*/
- uvm_{component,object}的创建
每一个uvm_{component,object}在例化的时候都应该给予一个名字(string);
//---------factory创建的方式
//创建uvm_component对象
comp_type::type_id::create(string name, uvm_component parent);
//创建uvm_object对象
object_type::type_id::create(string name);
3.4 uvm_coreservicr_t类
- uvm_coreservicr_t会被UVM系统在仿真开始时例化一次,用户不需要额外操作;【红宝书P265】
- 该类内置了UVM世界核心的组件和方法,它们主要包括:1.唯一的uvm_factory,该组件用来注册、覆盖和例化;2.全局的report_server,该组件用来做消息统筹和报告;3.全局的tr_database,该组件用来记录transaction记录; 4.get_root()方法用来返回当前UVM环境的结构顶层对象。
- 该类并不是uvm_component或者uvm_object,它也并没有例化在UVM环境中,而是独立于UVM环境之外的。
4 覆盖方法
4.1override概述
-
覆盖机制可以将原来所属的类型替换为另外一个新的类型;
-
在覆盖之后,原本用来创建原属性的请求,将由工厂来创建新的替换类型;
- 无需修改原始代码,保证原有代码的封装性;
- 新的替换类型要和被替换类型兼容,否则句柄赋值会失败,因此新类型要继承于原有类型;
-
可以通过子类覆盖父类,修改父类的原本属性;
-
想要实现覆盖特性,原有类型和新类型均需要注册;
-
当使用create()来创建对象时:
- 工厂会检查原有类型是否被覆盖;
- 如果被覆盖,则创建一个新类型的对象;
- 如果没有覆盖,则创建一个原有类型的对象;
-
覆盖发送时,可以使用“类型覆盖”or“实例覆盖”
- 类型覆盖,UVM层次结构下所有原有类型都被覆盖类型所替换;
- 实例覆盖,在某些位置中的原有类型会被覆盖类型所替换;
4.2 set_type_override()
4.3 set_inst_override()
4.4 覆盖实例
4.5 确保正确覆盖的代码要求
4.5
- 将UVM环境中所有的类都注册到工厂中,通过工厂来创建对象;
- 使用某些类的时候,确保该类已经被导入到当前域中;
- 注意句柄名称的一致性;
- 在同一顶层build_phase()中覆盖方法应发生在对象创建之前;
- 覆盖类最好是原始类的子类,调用成员放也要声明为虚方法;
- 通过$case()进行动态类型转换;
- 如何使用覆盖相关的函数
- 有多个类提供与覆盖有关的函数
- 常用的是orig_type::type_id
修改日志
2021年10月26日 第一次草稿 待解决问题- 宏 为什么需要宏
- uvm_coreservicr_t类
- 覆盖方法的两个函数
- 两个覆盖实例