为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

UVM实战指南

2021-05-21 8页 doc 511KB 32阅读

用户头像 机构认证

夕夕资料

拥有专业强大的教研实力和完善的师资团队,专注为用户提供合同简历、论文写作、PPT设计、计划书、策划案、各类模板等,同时素材和资料部分来自网络,仅供参考.

举报
UVM实战指南HYPERLINK"http://electron64.blog.163.com/blog/"\l"m=0&t=1&c=fks_084066087094087064080095087095085086087067087085095068084"http://electron64.blog.163.com/blog/#m=0&t=1&c=fks_084066087094087064080095087095085086087067087085095068084Callback——最简单的callback  2012-01-2...
UVM实战指南
HYPERLINK"http://electron64.blog.163.com/blog/"\l"m=0&t=1&c=fks_084066087094087064080095087095085086087067087085095068084"http://electron64.blog.163.com/blog/#m=0&t=1&c=fks_084066087094087064080095087095085086087067087085095068084Callback——最简单的callback  2012-01-2122:06:01|  分类: HYPERLINK"http://electron64.blog.163.com/blog/"\l"m=0&t=1&c=fks_084066087094087064080095087095085086087067087085095068084"\o"SystemVerilog"SystemVerilog|字号 订阅在RVM、VMM、OVM/UVM中,常常提到callback这个概念。指在事先设置好的地方留下一个接口,通过向这个接口添加一些函数对象,来达到不改变代码结构而动态修改代码行为。下面用systemverilog来举一个简单的callback例子: 1 class callback; 2  3   virtual task cb_pre_run( ); 4     $display("basecallbackrun"); 5   endtask:cb_pre_run 6    7 endclass:callback 8  9 class widget;10 11   callbackcb_queue[$];12 13   function void add_cb(callbackcb);14     cb_queue.push_back(cb);15   endfunction:add_cb16 17   task run();18     //addcallbackhere19     foreach(cb_queue[i]) begin20       cb_queue[i].cb_pre_run();21     end22     $display("widgetrun....");23   endtask:run24 endclass:widget25 26 module top;27 28 class ext_callback extends callback;29   task cb_pre_run();30     $display("extcallbackrun");31   endtask:cb_pre_run32 endclass:ext_callback33   widgetw;34   callbackcb0;35   ext_callbackcb_ext;36 37   38   initial begin39     w = new;40     cb0 = new;41     cb_ext = new;42     w.run;43     w.add_cb(cb0);44     $display("===========  AfterAddbaseCallback");45     w.run;46     w.add_cb(cb_ext);47     $display("===========  AfterAddextentionCallback");48     w.run;49   end50   51 endmodule; //top    在sysverilog中,没有函数指针的概念,因此必须将函数包装成为一个对象,就是上面例子中的callbackclass.而为了在widget的对象中使用这个函数对象,必须事先在设计好的调用点对callback对象中的函数进行逐个调用(代码19-21行)。    widget的对象事先并不知道有多少callback对象,而是将所有的callback对象放到自己的一个callback对象队列中(cb_queue)。然后逐个对这个队列中的所有对象进行函数调用。    上面的程序编译执行后,结果如下:widgetrun....===========AfterAddbaseCallbackbasecallbackrunwidgetrun....===========AfterAddextentionCallbackbasecallbackrunextcallbackrunwidgetrun....    可以看出,在执行的过程中,可以对widget对象进行动态的添加callback,从而动态的改变widget对象的动作。    上面的例子非常简单,仅仅是输出一些讯息而已,有一些局限:这个callback结构并不能够真的改变widget对象的内部成员,以及处理的数据内容,仅仅能够输出一些讯息。对每一个widget的对象,都需要单独添加相关callback对象,假如程序中又创建了一个新的widget对象,那么这个对象的callbackqueue初始是空的,也就是没有callback。必须再次添加才能让这个新的widget调用相应的callback功能。callback只有一个地方,可以扩展到多个地方。另外也可以使用function,而不仅仅是task.工厂模式的简单理解首先,如果一个客户要用到一款手机,一般的做法是客户去创建一款手机,然后拿来用: 这时,客户需要知道怎么去创建一款手机,客户和手机就紧密耦合在一起了.为了降低耦合,就出现了工厂类,把创建手机的操作放到了工厂里面去,客户直接使用工厂的创建手机方法,传入想要的手机型号就行了,而不必去知道创建的细节. 随着手机种类越来越多,简单工厂模式出现了弊端,每次新加入手机品种,工厂类都要加入新的创建逻辑.这时我们就可以把工厂类定义成了接口,而每增加一种新的手机,就增加该手机对应工厂类的实现,这样工厂的设计就可以扩展了,而不必去修改原来的代码: 随着工厂规模的继续扩大,工厂开始生产充电器了.这时候工厂有二个系列的产品:手机和充电器.而手机必须使用对应的充电器才能使用.这时候分别使用一个手机工厂和一个充电器工厂都不能满足我们的需求,我们必须确认手机跟充电器的对应关系.我们把工厂改造一下,把手机工厂跟充电器工厂联系在一起:抽象工厂模式工厂方法模式简单工厂模式UVM实战——第1部分  2010-10-3121:54:15|  分类: HYPERLINK"http://electron64.blog.163.com/blog/"\l"m=0&t=1&c=fks_084066087094087064080095087095085086087067087085095068084"\o"SystemVerilog"SystemVerilog |  标签:HYPERLINK"http://electron64.blog.163.com/blog/"\l"m=0&t=3&c=uvm"uvm  |字号 订阅验证的复杂度已经明显超过设计。为了处理复杂度,面向对象,设计模式等软件设计的思想逐渐渗透到了硬件设计领域。UVM的适时提出,有望能够尽早一统江湖,不再有各门各派军阀割据。最近,出了一本UVM新书,工作之余,我抽空进行翻译,供大家参考。英文来源:HYPERLINK"http://www.low-powerdesign.com/article_Cadence-UVM_082310.html"http://www.low-powerdesign.com/article_Cadence-UVM_082310.html UVM实战指南——第1部分这篇文章是新书《APracticalGuidetoAdoptingtheUniversalVerificationMethodology》的第四章UVMlibrary基础的节选。这一章的后续会在之后4周的周一连续发表。如果等不及,可以到amazon.com网站购买。作者:SharonRosenbergandKathleenA.Meade,CadenceDesignSystemsUVM是功能验证的第一个最佳实践和方法学。如之前提到,UVM实现了成熟的高级验证方法。尽管其类库可以任意使用,我们强烈建议按照后续章节描述的方式来使用,因为这些方法源自于成功经验。这一章讲解库的结构以及基本功能,重点放在大多数验证环境所需要的基本特征上。 注意:为了简化,例子并没有完全遵循UVM建议的架构和方法学。这一章主要包括:使用UVM库基本类TLM端口工厂模式消息和汇报配置机制4.1使用UVM库为了使用UVM库,用户需要:编译UVM包的顶层文件:uvm_pkg.sv在所需要的地方导入uvm_pkg包含UVM宏4.1.1HelloWorld例子下面的例子功能是在屏幕上显示消息:"HelloWorld!” 1//CompiletheUVMpackage 2 `include“uvm_pkg.sv” 3modulehello_world_example; 4   //ImporttheUVMlibraryandincludetheUVMmacros 5    importuvm_pkg::*; 6    `include“uvm_macros.svh” 7   initialbegin 8        `uvm_info (“info1”,“HelloWorld!”,UVM_LOW) 9    end 10endmodule:hello_world_example第1-2行:注释用来提醒需要编译UVM库。uvm_pkg.sv是UVM顶层文件,此文件将所有的UVM文件放在一个systemverilog文件包中。注意:SystemVerilog包需要在模块以外进行编译。建议用命令行方式进行编译。由于包常被多个单元使用,不要将包的编译绑定到某个指定的单元。第5行:当库已经编译,用户可以在任意编译单元导入此systemverilog包第6行:必须分别包含UVM宏,因为宏属于编译指令,不会在多个编译步骤中保持存在。为了避免重复编译整个库,宏被分开包含。(每个需要用的宏的文件都必须包含)第8行:`uvm_info宏属于UVM消息打印功能的一部分。UVM消息打印允许格式化以及控制屏幕显示。在这里,我们仅仅打印消息“HelloWorld!”4.1.2UVM库使用指南为了避免命名冲突,避免在全局环境中导入uvm_pkg.其他的package也同样适用此原则(避免全局环境中导入)顶层文件一般如下格式`ifndef_SVH `define_SVH ...文件内容 `endif这种方式允许UVM库被多个地方引用而避免重复声明,一起编译的时候仅编译一次。建议用户在自己的UVM文件中也使用此方式。在Cadence的IncisiveEnterpriseSimulator(IES)仿真器中运行仿真器自带的UVM库:%irun-uvm myfile.sv使用非仿真器自带的UVM库,使用命令行:%irun-uvmhome$UVM_HOME myfile.sv4.2基本类图4-1类图描绘了UVM库中的一些类。这些类提供了一些自动机制,可以用来衍生出用户自定义的类以及类的行为。除了自动机制,这些基类还提供了支持统一和重用的API。 注意:此图没有显示uvm_transaction类。尽管这个类仍然属于库,AccelleraTSC并不建议使用它。(建议使用uvm_sequence_item) 后续章节讨论uvm_object和uvm_component抽象类4.3uvm_object类抽象类uvm_object是所有UVM数据类型的基类。他的主要功能是定义完成了一系列通用的操作方式,比如创建,复制,打包/解包(pack/unpack),比较,打印,以及记录(record).从uvm_object衍生出来的类必须实现类似create()和get_type_name()这样的纯虚函数。以下代码演示了一个没有使用UVMobject类的AMBAAPB传输的例子实例4–1: 非UVM类定义 1 typedef enum bit {APB_READ,APB_WRITE}apb_direction_enum; 2 class apb_transfer; 3   randbit[31:0]addr; 4   randbit[31:0]data; 5   randapb_direction_enumdirection; 6    function voidprint(); 7      $display("%stransfer:addr=%hdata=%h",direction.name(),addr,data); 8    endfunction :print 9 endclass :apb_transfer 上面简单的例子包含了一个几乎所有交易(transaction)都有的print()方法。大部分数据项都需要打印,复制,比较,打包,解包以及其他功能。如果让开发者去自已去定义这些功能,将不方便复用,环境整合者必须学习从多个地方得到的不同类的使用规则以及行为特征。UVM库通过引入uvm_object基类解决了这个问题。基类定义了一些通用的服务。测试向量中所有的类都必须间接或直接由uvm_object派生出来。UVM类库也实现了一些宏,这些宏能够自动实现打印,复制,克隆,打包(pack),解包(unpack)方法等等。 实例4–2:从uvm_object继承而来的APB传输类 1 typedefenumbit{APB_READ,APB_WRITE}apb_direction_enum; 2 classapb_transferextends uvm_object; 3   randbit[31:0]addr; 4   randbit[31:0]data; 5   randapb_direction_enumdirection; 6   //Controlfield-doesnottranslateintosignaldata 7   randintunsignedtransmit_delay;//delaybetweentransfers 8   //UVMautomationmacrosfordataitems 9     `uvm_object_utils_begin (apb_transfer) 10      `uvm_field_int (addr,UVM_DEFAULT) 11      `uvm_field_int (data,UVM_DEFAULT) 12      `uvm_field_enum(apb _direction_enum,direction,UVM_DEFAULT) 13      `uvm_field_int(transmit_delay,UVM_DEFAULT|UVM_NOCOMPARE) 14    `uvm_object_utils_end 15  //Constructor-requiredUVMsyntax 16  functionnew(stringname="apb_transfer"); 17    super.new(name); 18  endfunction:new 19endclass:apb_transfer第9-14行:UVM自动宏第16-18行:在数据对象中构造函数并不是必须的。如果使用构造函数,它的所有的参数都必须有缺省值.(针对uvm_object如此,但是uvm_component并不是这样,其parent参数并没有缺省值,因为不可能在类中知道其父组件)4.3.1UVM自动域使用`uvm_object_utils_begin(TYPE)和`uvm_object_utils_end宏来完成UVM对象的基本操作声明。实现get_type_name()函数,此函数返回内容为这个对象类型名字的字符串实现create()函数,此函数通过调用指定类型的构造函数来创建一个对象在工厂中注册此类型,以便在测试向量中的其他地方能够被重载实现一个静态方法get_type(),此方法在工厂操作中需要被用到`uvm_field_*宏将自动实现指定域的一些对象方法:print(),copy(),clone(),pack(),unpack(),compare(),以及record()。支持嵌套对象以及用户自定义。宏语法如下:语法:`uvm_field_*(field_name,flag)“field_name”必须是类的某个属性的标识符;“flag”用来定制此域的自动化。“flag”是一数字,可以用或“|”或者“+”进行组合。此语法适合:对象、字符串、事件(event)、实数、队列、以及不同类型的数组。域自动有多种形式,请参考UVM参考手册。 4.3.2uvm_object定义指南建议从uvm_sequence_item继承对象,此方式能够给对象增加一些额外的域,同时允许对象成为uvm_sequence随机的一部分。对`uvm_field_*宏使用UVM_DEFAULT作为“flag”参数(而不是UVM_ALL_ON)。目的是为了让UVM架构增加一些缺省下并不打开的自动功能。其他一些标志是用来去掉一些自动化功能的。在构造函数中的参数中将类名字设置为缺省值不要忘记调用super.new(name),作为构造函数的第一个语句另一个不同的宏包含了类型参数:`uvm_object_param_utils*`uvm_field_object缺省是深度操作。如果你使用另外一个对象,请使用UVM_REFERENCE标志来禁止深度操作。实例4-3演示了域自动宏的更多用法,包括类组合和动态数组。此例子中的yapp_packet类包含一个pkt_header域。实例4–3:uvm_object自动域 1  classpacket_headerextends uvm_object;  //PacketHeaderclass 2    randbit[5:0]length; 3    randbit[1:0]addr; 4     `uvm_object_utils_begin (packet_header) 5       `uvm_field_int (length,UVM_DEFAULT) 6       `uvm_field_int(addr,UVM_DEFAULT) 7     `uvm_object_utils_end 8  endclass:packet_header9  typedefenumbit{BAD_PARITY,GOOD_PARITY}parity_e; 10classyapp_packetextends uvm_object; 11   //PhysicalData 12   randpacket_headerheader;//pkt_headerclasscontains:addr,length 13   randbit[7:0]payload[]; //dynamicarrayintherange[1:63] 14   bit    [7:0] parity;   //calculatedinpost_randomize() 15   //ControlKnob 16   randparity_eparity_type; //randomizedtodetermineparitytype 17   randintpacket_delay; 18   //UVMmacrosforbuilt-inautomation-Thesedeclarationsenableautomation 19   //ofthedata_itemfieldsandimplementcreate()andget_type_name() 20    `uvm_object_utils_begin (yapp_packet) 21      `uvm_field_object (header,UVM_DEFAULT) 22      `uvm_field_array_int (payload,UVM_DEFAULT) 23      `uvm_field_int (parity,UVM_DEFAULT) 24      `uvm_field_enum(parity_e,parity_type,UVM_DEFAULT) 25      `uvm_field_int(packet_delay,UVM_DEFAULT|UVM_DEC|UVM_NOCOMPARE) 26    `uvm_object_utils_end 27   //Constructor-requiredsyntaxforUVMautomationandutilities 28   functionnew(stringname="yapp_packet"); 29     super.new(name); 30     header=packet_header::type_id::create("header");//allocationusingthefactory 31   endfunction:new 32endclass:yapp_packet第1行:header_packet由uvm_object继承而来第21行:如果这是一个参考类,那么我们需要使用UVM_REFERENCE标志来避免深度操作。payload是一个动态数组,使用一个特殊的宏可以打印数组的所有成员。第24行:枚举类型语法有一个额外参数:`uvm_field_enum(,,)第30行:不用“header=new(“header”)”,我们使用工厂模式。用`uvm_object_utils实现的create()方法允许在另外项目和测试环境中扩充交易(transaction)。请参考第62页的“UVM工厂”了解更多信息。 4.3.3UVM对象自动用法实例下面的例子演示了UVM库内建的自动特性。假定实例4-2中的apb_transfer已经定义。 实例4–4:UVM对象的自动特性的用法 1moduleautomation_example; 2   //ImporttheUVMlibraryandincludetheUVMmacros 3   importuvm_pkg::*; 4    `include“uvm_macros.svh” 5   //IncludetheAPBtransferclass 6    `include“apb_transfer.sv” 7   apb_transfermy_xfer,tx1,tx2,tx3; 8   initialbegin 9      my_xfer=apb_transfer::type_id::create("my_xfer"); 10    if(!my_xfer.randomize()) 11       `uvm_fatal(“RANDFAIL”,”cannotrandomizemy_xfer”) 12    tx1=my_xfer;         //tx1andmy_xfersharethesamememory 13                                    //Createanewapb_transfer 14    tx2=apb_transfer::type_id::create("tx2"); 15    tx2.copy(tx1);         //Copiesfieldsfromtx1totx2 16    $cast(tx3,tx1.clone()); //Createsanewapb_transferandcopyall 17                                        //  specifiedfieldsfromtx1totx3 18    if(!tx3.compare(tx2)) 19      `uvm_error(“CompareFailed”,“Thecomparisonfailed”) 20    my_xfer.print();       //Printsmy_xferinatableformat 21    my_xfer.print(uvm_default_tree_printer); //Printsin“tree”format 22 end 23endmodule:automation_example为了使用UVM库,必须导入UVM包,并且包含文件"uvm_macros.svh”.此例子创建、随机化、复制、克隆、并且打印apb_transfer.使用宏自动实现一个列表以及树形格式化的打印方法print()。缺省的表格格式如下:NameTypeSizeValuemy_xferapb_transfer-@560addrintegral32'hb2cbb864dataintegral32'heba598d7directionapb_direction_enum1APB_WRITEtransmit_delayintegral32'h6缺省的树形格式如下: my_xfer:(apb_transfer@560){ addr:'hb2cbb864data:'heba598d7direction:APB_WRITE transmit_delay:'h6 }下面的输出显示了第40页实例4-3中随机的yapp_packet。此封包包括一个头对象,一个具有动态数组类型的payload。下面表格中数值很容易格式化并打印如下表格: NameTypeSizeValuemy_packetyapp_packet-@570headerpkt_header-@596lengthintegral6'h30addrintegral2'h2payloadda(integral)48-[0]integral8'h7bintegral8'he7 integral8'h8c............ integral8'hf3 integral8'h78[47]integral8'he1parityintegral8'h74parity_typeparity_e1GOOD_PARITYpacket_delayintegral32'd8自动域宏将实现一个字符串打印方法:sprint(),此方法将返回一个可以用来格式化显示的字符串。打印格式是可以配置的,详细请参考UVM参考手册。注意:表格打印使用的是最复杂的格式化功能,因此运行代价最高。如果你的仿真器要打印大批量的交易(transaction),最好使用树形格式。4.3.4使用UVM自动域使用UVM自动域是可选的。尽管用户可以自己实现这部分功能,我们还是建议使用自动宏来实现。使用宏有以下优点:高效率:如果自己实现,会需要很多时间来实现这些子例程以及丰富的可选项可扩展性:在嵌套的对象中增加一个域需要了解UVM的原始实现方式,这常常需要很强的技巧。而用自动宏只需要一行语句即可实现的一致性对复用很重要——例如,如果每个开发者都是用自行开发的print()方法,那么使用多个包的整合人员将不得不分析各不一样的日志文件,包括域头,值,基,以及结构,这些都属于开发者的各自喜好。可维护性——维护少数行数的代码简化了UVM开发者的工作代码正确性——对于大量的数据对象,很难确保所有的例程都是正确的,BUG会出现在不恰当的时间请注意,这些宏是属于库的内部实现,已经很成熟,不需要用户来调试。对缺省的对象函数print()进行调试就好像对verilog仿真器中的$display函数进行调试。总之,我们见过一些用户最初比较担心宏的使用,后来一旦他们尝试使用宏,就变得十分喜欢它,成为宏的爱好者,并感叹道:“他们真好用!”UVM实战指南——第2部分  2010-12-2420:54:22|  分类: HYPERLINK"http://electron64.blog.163.com/blog/"\l"m=0&t=1&c=fks_084066087094087064080095087095085086087067087085095068084"\o"SystemVerilog"SystemVerilog |  标签:HYPERLINK"http://electron64.blog.163.com/blog/"\l"m=0&t=3&c=uvm"uvm  |字号 订阅英文来源:HYPERLINK"http://www.low-powerdesign.com/article_Cadence-UVM_083010.html"http://www.low-powerdesign.com/article_Cadence-UVM_083010.html译者序:UVM的核心组件,以及UVM仿真阶段的控制是整个验证环境的基本零部件,必须掌握。UVM的参数config机制对验证增加了许多灵活性和复用性,在参数配置和SystemVerilogInterface信号传递上起到了关键作用。4.4uvm_component类所有的UVM验证环境的组件,包括环境和测试项都是直接或者间接由uvm_component类继承而来。此类是一个准静态类,只能在仿真开始的时候创建(构建[build]阶段).从此类继承的用户自定义类继承了许多内建的自动化功能。注意:一般来说,通过从某个方法学构建的一系列类继承来设计自己的类,这系列类本身都是由uvm_component继承而来。由于提供各种功能的类都是由此类派生,理解uvm_component类是非常重要的。下面章节描述uvm_component类的一些功能,以及如何使用。关键功能是:Phasingandexecutioncontrol阶段(phase)执行控制Hierarchyinformationfunctions层次信息功能Configurationmethods配置方法Factoryconveniencemethods工厂方法Hierarchicalreportingcontrol层次化汇报控制4.4.1仿真阶段控制方法在Verilog/VHDL类似的硬件描述语言中,在仿真开始之前静态构建各个实例的层次结构,保证了在跑仿真之前,所有的实例都连接存在且正确连接。在Systemverilog中,类对象是在运行时被创建,这就引出一些问题:什么时候进行传输交易产生和执行比较安全?什么时候能够确保所有的UVM组件都已经被创建?可以连接什么TLM端口?尽管每个开发者都能够设计各自的同步方式,SystemVerilogUVM类库提供了一系列的阶段(phase)方法进行环境同步,而不需要事先设计。这些阶段给用户提供了一些钩子,实现在关键的时间点执行一些逻辑。比如,如果需要在仿真结束的时候执行检查逻辑,可以扩展check()阶段方法,在其中嵌入执行代码。那么这些代码在仿真过程中将会在想要的时间点被执行。除了run阶段方法之外,剩下所有的内建阶段方法的执行是在零时间内完成。请参考UVM类参考手册中的uvm_phase文档获得更多的信息。从高层次来看,已有的阶段方法是(以仿真执行的顺序):new()—尽管他不是一个UVM阶段函数,但是组件的构造函数是组件被创建生成时第一个执行的函数。uvm_component构造函数包含两个参数:一个字符串name参数代表组件的名称,以及一个对组件父亲的引用。建议不要使用构造函数参数的缺省值,这样可以保证用户提供有意义的名字和父类。构造函数格式如下:class street extends uvm_component;   `uvm_component_utils(street)   functionnew(stringname,uvm_componentparent);      super.new(name,parent);    endfunction :new endclass :street技巧:关于构造函数的使用指南所有的组件类型的构造函数必须使用名称参数和父类参数。因为工厂需要提供名称参数和父类参数来构建组件。不要使用缺省参数,以确保用户必须给这两个参数提供有意义的值使用简洁,意思清晰的名称对于组件数组,名字使用索引:agent[index],比如env.agent[0].monitor,env.agent[1].monitor,等等build()—第一个UVM阶段方法是build()方法,对每个组件会自顶向下自动调用。此方法可以对子组件进行配置,然后创建子组件。由于构造函数不是完全多态的,因此我们使用此方法来构建在构造函数中没有被创建的子组件。因为build()方法是自顶向下调用,所以父类的构造配置将在子类build()方法之前完成。一些关于build()使用指南:每个build()的实现必须先调用super.build(),除非此组件明确关闭了自动配置功能。调用super.build()会通过apply_config_settings方法调用来完成更新组件的配置域。尽管不建议使用,父组件可以显式的在parent.build()中调用子组件的build().调用super.build()确保了build()不被调用两次。在build()中分配子组件,而不是在构造函数中分配子组件。这样可以允许组件在分配层次结构之前可以配置。由于构造函数不是多态的,所以除非在build()函数中来创建结构,否则一个继承类不可能改变结构。如果组件在build()阶段之后被分配,UVM将会报错。子组件的配置需要在build()方法中,子组件被创建之前完成。如果通过重载build方法来改变组件的结构,此时不能够调用super.build(),因为这会导致父类的build被执行。如果你仍然想要uvm_component的build()方法的行为,可以通过调用uvm_component::build()来完成,这个方式会直接跳过父类的build方法。.class my_derived_comp extends mycomp;     function new(stringname,uvm_componentparent);        super.new(name,parent);     endfunction     function voidbuild();         uvm_component::build();//不调用super.build()        ...//做其他事情    endfunction endclassconnect()—此阶段在build()之后执行。由于所有的子组件在build()阶段自顶向下都被创建,用户可以认定在connect()被调用的时候,所有组件的拓扑结构都已经成功创建.此方法用来做事物级建模(TLM)的连接,指针引用的赋值,以及虚拟接口(virtualinterface)的赋值。end_of_elaboration()—end_of_elaboration()阶段确保所有的连接,所有的引用都在connect阶段完成。在end_of_elaboration阶段执行之前,UVM完成了所有的TLM绑定,因此在此阶段,所有的端口绑定都已经建立,可以被访问使用。start_of_simulation()—此阶段提供了一个机制来避免仿真0时刻各个组件之间的互相依赖。组件在此阶段初始化,确保在run阶段开始的时候,一切都已经正确初始化。run()—run()阶段是唯一的一个耗时间的阶段,它定义了组件运行时的主要功能。由于它被定义为任务(task)类型,所以可以消耗仿真时间。当组件从run任务返回时,并不代表run阶段结束。有可能其内部创建的进程还在继续执行。run阶段是通过global_stop_request()任务来完成。此任务在发生超时,或者在对象机制使用的时候调用进程终止方法。extract()—此阶段用来在仿真结束,,在检查校验阶段之前,提取仿真的结果。此阶段可以用来收集断言错误的个数,覆盖率,以及DUT内部讯号和寄存器的值,组件内部变量值,组件的统计信息及其他信息。此阶段执行不耗时间(消耗0时间),是一个函数调用。调用方式是自底向上。(译者补充:从叶子(leaf)组件的extract函数开始调用,深度优先)check()—在前阶段(extract阶段)得到了重要的仿真结果,check阶段对结果进行分析判断,以此决定整个仿真的最终结论。此阶段也是一个0执行时间的函数调用,自底向上调用。report()—此阶段最后执行,用来将结果输出到文件或者屏幕。此阶段是一个0执行时间的函数,自底向上调用。尽管所有这些钩子方法在uvm_component以及他的子类中定义,只需要实现用到的相关(阶段)函数/任务(不需要全部实现).组件不需要对子组件使用`uvm_field_object宏,组件在被创建的时候总是被提供其父组件,从而构建了所有组件的层次结构。仿真阶段和层次构造的例子在后面给出:4.4.2层次信息函数在仿真时,组件树是静态的。组件对层次信息非常注意,可以查询其父类,子类,以及他们在层次结构中的位置。相关的uvm_component成员函数如下:get_parent()—返回父组件句柄,如果没有,返回nullget_full_name()—返回此对象的完整层次结构名字.缺省实现是将层次结构中的父类和其叶子对象相拼接。get_child(string_name)—根据参数名字返回子组件的句柄以下例子演示了UVM仿真的阶段控制,以及组件的层次信息方法的使用。包含了street,city,state的组合。并演示了get_child(),get_parent(),以及get_full_name()的功能。不建议使用new()来创建对象。请参考62页的"UVM工厂"章节。实例4-5: uvm_component仿真阶段控制以及层次信息相关方法此例子演示了组件层次,包括州,城市,街道等对象实例。注意构造函数以及build(),run(),end_of_elaboration()阶段函数/任务的使用。用户通过阶段钩子函数/任务来完成想要的功能。从run_test()出发,各阶段开始按步骤自动开始执行。此例子也展示了get_child(),get_parent()和get_full_name()函数得到层次信息的功能module test;import uvm_pkg::*;`include"uvm_macros.svh"class street extends uvm_component; `uvm_component_utils(street)  function new(stringname,uvm_componentparent);    super.new(name,parent);  endfunction :new  task run();   `uvm_info("INFO1","Ivacationedherein2010",UVM_LOW)  endtask :runendclass :streetclass cityextendsuvm_component; streetMain_St; `uvm_component_utils(city)  function new(stringname,uvm_componentparent);    super.new(name,parent);  endfunction :new  function voidbuild();//notethatweallocateinthebuild()    super.build();    Main_St=street::type_id::create("Main_St",this);  endfunction :build  task run();   uvm_componentchild,parent;   stringpr,ch;   child=get_child("Main_St");   parent=get_parent();   pr=parent.get_full_name();   ch=child.get_name();   `uvm_info(get_type_name(),$psprintf("Parent:%s Child:%s",pr,ch),UVM_LOW)  endtask :runendclass :cityclass stateextendsuvm_component;  cityCapital_city; `uvm_component_utils(state)  function new(stringname,uvm_componentparent);   super.new(name,parent);  endfunction :new  function voidbuild();   super.build();   Capital_city=city::type_id::create("Capital_city",this);  endfunction :build function voidend_of_elaboration();   this.print(); endfunction :end_of_elaborationendclass :statestateFlorida=state::type_id::create("Florida",null);stateNew_York=state::type_id::create("New_York",null);//StartUVMPhasesinitialrun_test();initial#100global_stop_request();endmodule :test第4行:street类定义。由于street没有子组件,所以不需要build()方法。new()和build()方法仅仅调用super.new()和super.build().【补充说明:如果没有定义build()方法,将会调用父类中的build方法,也就是super.build()方法。这是虚函数的特点:如果有就用自己的,如果没有,就用父类的】第9行:run()方法打印一些信息第13行:city组件中包含一个street子组件第19行:street在build()阶段通过工厂模式被创建第26行:在run()方法中,city调用get_child(),得到street子组件的信息。第27行:get_parent()函数返回city的父组件,即state.第28行:get_full_name()函数返回关于父组件的完整的层次结构第47-48行:实例化创建两个state对象,也通过工厂模式创建第50行:调用run_test()开始UVM的各阶段仿真。结果如下:  ---------------------------------------------------------------------- Name                    Type               Size               Value ---------------------------------------------------------------------- Florida                 state               -                   @580  Capital_City          city               -                   @711    Main_St             street             -                   @712 ---------------------------------------------------------------------- ---------------------------------------------------------------------- Name                    Type               Size               Value ---------------------------------------------------------------------- New_York                state              -                   @638  Capital_City          city               -                   @776    Main_St             street             -                   @769 ---------------------------------------------------------------------- UVM_INFO@0:New_York.Capital_City[city]Parent:New_York Child:Main_St UVM_INFO@0:New_York.Capital_City.Main_St[INFO1]Ivacationedherein2010 UVM_INFO@0:Florida.Capital_City[city]Parent:Florida Child:Main_St UVM_INFO@0:Florida.Capital_City.Main_St[INFO1]Ivacationedherein2010 Simulationcompletevia$finish(1)attime100NS+0 ./uvm_st_ci_st.sv:75initial#100$finish;4.4.3组件uvm_top有一个特殊的UVM组件叫做"uvm_top"。此组件是uvm_root类的单一实例,也是由uvm_component继承而来。uvm_top组件负责对所有的组件进行阶段控制,并且提供了查找功能(uvm_top.find()和uvm_top.find_all()),方便定位一些特定的组件。uvm_top组件还提供了一个存储全局配置的地方。调用set_config_*()函数相当于调用uvm_top.set_config_*().对消息打印函数也如此,调用uvm_report_*(或者`uvm_info/warning/error/fatal)等价于调用uvm_top.uvm_report*函数。4.5UVM配置机制通用的验证组件复用的一个重要方面是其具备可以配置为期望的工作模式的能力。UVM提供了一个灵活的配置机制,允许在运行时配置属性和组件拓扑结构,而不需要派生和使用工厂模式。组件属性的配置通过set_config*应用接口界面(API)来实现,包括以下3个API:virtualfunctionvoid set_config_int (stringinst_name,stri
/
本文档为【UVM实战指南】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
热门搜索

历史搜索

    清空历史搜索