马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
UVM验证方法学 基于SystemVerilog验证语言的UVM功能验证 1、SV 面向对象编程OOP 2、UVM 验证平台TB 3、事务级建模Transaction modeling 4、产生激励序列Stimulus sequences 5、工厂模式和配置机制Factory and configuration mechanism 6、UVM组建之间的通信机制TLM 7、覆盖率和记分板Coverage and Scoreboard 8、UVM callback 9、Virtual sequencer 和 sequence
10、UVM component phases 机制 11、寄存器抽象层RAL
一,SV OOP复习 OOP封装 继承 多态 编码规则 特殊类:参数类 自定义类 单例类 代理类proxy class
工厂模式factory
封装性 SV中的class: 变量用于数据建模、子程序用于操作数据、变量和子程序称为类的成员。 要跑时间用task,不用时间就用function
继承 通过基类派生新类 新类会继承基类的所有数据和数据处理 重用:子类兼容父类 $cast(etr,tr);强制类型转换
多态 调用哪个子程序,取决于tr的类型,不管子程序是否为virtual 如果子程序不是virtual methods 就看句柄类型,不用看对象类型
如果是virtual methods 看对象类型(虚方法) 利用虚方法可以开发通用型的类子程序
OOP编程规则:在class之外定义子程序 将所有子程序声明在class内:extern 将数据和数据处理放在一屏代码中,可以减少bug 在class文件之外实现函数体 作用域符号::
参数化的class 为通用功能编写参数化的类 通用代码重用 类似与参数的module,在实例化时传递参数 class stack #(type T=int);
自定义的class 应用场景1: 在声明之前使用类 两个类彼此使用对方的句柄 typedef class C2; class C1; C2 inside_C1; ... endclass C1
class C2;
C1 i_an_inside; ... endeclass
应用场景2:简化参数类的编码 typedef stack #(bit[31:0]) stack32;
Static property 静态变量/数据 在class的定义中声明静态变量static 可以存储本地信息,例如生成的对象的数量index 类的所有对象都共享该静态变量,在编写test的时候,可以用变量id来区分transaction的索引值。
Static method静态子函数/方法 不用句柄就可以调用子函数/方法 transaction::print_count();
只能处理静态变量
Singleton class 单例类 用于定于全局行为,比如打印、工厂 单例类不存在对象 只包含静态变量和子函数
class print; static int err_count=0, max_errors=10; static function void error(sring msg); $display("@%t:ERROR%s",$realtime,msg); if(err_count++>max_errors) $finish; endclass:error endclass:print
Singleton object单例对象 单例对象时一个全局可见/可操作性的对象,提供定制化服务/函数 有且仅有唯一的对象,在编译时创建 在仿真时全局可见/可操作性 可以有静态或者非静态类成员。 class factory; static singleton me =get(); static function singleton get(); if(me==null)me==new();return me; endfunction:get local function new();endfunction:new extern function void print(); endclas:fatory
Proxy class 代理类 提供create()等通用型的子函数 class proxy_class #(type T=base); typedef proxy_class #(T)this_type; static this_type me=get();
static function this_type get(); if(me==null)me=new();return me; endfunction static function T creat(); create=new(); endfunction endclass
class environment; transaction tr;driver drv; function new(); tr=transaction::proxy::create();//creat函数替代了new函数
drv=drive::proxy::createa(); endfunction endclass:environment
Factory mechanism 工厂机制 创建工厂,需要两层代理类 1、虚代理类(virual proxy base class) 2、派生代理类,是实现全部功能,类似工厂中的模具。 虚代理基类() 1、代理基类要具有的多态属性 2、为代理服务提供抽象的接口应用程序:创建对象:new 获取类型名称:get_name 模板
virtual class proxy_base; virtual function base create_object(string type_name); return null; endfunction pure virtual function string get_typename(); endclass
factory class 按需创建对象 维护代理对象登记表(registry) class factory; static proxy base registry[string]; static factory me=get(); static function factory get(); if(me==null)me=new();return me; endfunction
function void register(proxy_base proxy); registry[proxy.typename()]=proxy; endfunction
function base creat_object_by_type(proxy_base proxy,string name); proxy=find_override(proxy);// return proxy.creat_object(name);// endfunction
维护被覆盖的代理登记表:如果代理类被覆盖,创建覆盖后的类的对象 static string override[string]; static function void override_type(string type_name,override_typename); override[type_name]=override_typename; endfunction
function proxy_base find_override(proxy_base proxy); if(override.exists(proxy.get_typename())) return registry.[override[proxy.get_typename()]]; return proxy; endfunction endclass
Proxy class代理类 完成抽象的接口函数 在工厂中登记 利用工厂创建对象
class proxyf_class#(type T=base,string Tname="none")extend proxy base; typedef proxy_class#(T,Tname)this_type; static string type me_name=Tname; static this_type me=get(); static function this_type get(); factory f=factory=get();if(me=null)begin me=new();f.register(me);end return me; endfunction static function T creat(string name); factory f=factory::get() $cast(creat,f.creat_object by_type(me,name)); endfunction virtual function base create_object(string name); T obeject_represented=new(name); return object_represented, endfunction endclass:proxy_class
这么复杂的机制到底如何理解? 我们应该从上层往下去看它的调用关系!!!! case可以使用工厂机制替换验证平台中创建的任何对象,但却不需要修改验证平台的代码,提高了代码的可重用性 program automatic test; environment env; initial begin factory:verride type("deiver",new driver"); env=new(); ... end enprogram
class environment; driver drv;monitor mon; function new(); drv=driver::proxy::creat(); mon=monnitor::proxy::creat(); endfunction endclass:environment
说这么多,无非就是要记住工厂模式的两张表,注册表registry和覆盖表override。至于这些代码,大 如果有大佬想看完整的源码可以去UVM的库里面看,我境界低,我看不懂,太复杂了。 对于像我一样的萌新,首先就是要有一个工厂机制的思路,理解它是怎么通过不修改源代码去经行修改行为的操作的。
|