| |||
这一篇主要为大家介绍验证环境中的信息收集组件uvm_subscriber,数据结果比较组件(计分板)uvm_scoreboard,UVM环境uvm_env,测试用例uvm_test,配置验证环境的configuration以及验证顶层top,最后还将会给出一个仿真的结果。其在整个UVM验证平台中的结构如图3.1中的红色箭头所示。
图3.1 UVM验证平台整体结构
上一篇短文主要介绍了彩虹糖验证平台中的Sequencer,Driver,Monitor和Agent。以下是上一篇短文中主要介绍的类。
sequencer
class jelly_bean_sequencer extends uvm_sequencer#(jelly_bean_transaction);
driver
class jelly_bean_driverextends uvm_driver#(jelly_bean_transaction);
monitor
class jelly_bean_monitor extends uvm_monitor;
agent
class jelly_bean_agent extends uvm_agent;
一、功能覆盖率收集组件(function coverage subscriber)
功能覆盖率组件jelly_bean_fc_subscriber会对产生的彩虹糖作一个整体的记录。如第21行所示,jelly_bean_fc_subscriber在wirte函数中对从monitor中传递过来的transaction进行采样从而判断各种属性例如口味,颜色,甜度,酸度的彩虹糖是否都有产生,以及不同属性组合的彩虹糖是否也都有产生。如代码3.1所示,是jelly_bean_fc_subscriber的实现。
第7-10行:利用coverpoint建立功能覆盖率,分析彩虹糖的口味,颜色,甜度,酸度,确保各种属性的彩虹糖是否都有产生。
第11行:利用cross来建立功能覆盖率,分析彩虹糖各种属性的不同组合情况是否都有产生。
第19行:定义uvm_subscriber中的成员方法write函数,在write函数中进行功能覆盖率的采样。使得jelly_bean_fc_subscriber通过TLM端口和jelly_bean_monitor相连接之后可以使用monitor检测到的彩虹糖信息来判断各种属性的彩虹糖是否都有产生。
第21行:触发功能覆盖率的采样行为。
代码3.1 [class] jelly_bean_fc_subscriber的实现
二、记分板(scoreboard)
数据收集组件uvm_subscriber内设计了write函数和一个TLM端口analysis_export用来完成uvm_subscriber和其他组件之间数据的通信传输。uvm_subscirber的主要功能就是在write函数中体现的。在功能覆盖率收集组件jelly_bean_fc_subscriber中的write函数中触发功能覆盖率的采样,同样的记分板数据收集组件(scoreboardsubscriber)会在其write函数中调用jelly_bean_scoreboard的check_jelly_bean_taste函数来检查收集到的彩虹糖信息。check_jelly_bean_taste主要来检查DUT即我们的彩虹糖评测员(jelly_bean_taster)的反馈信息是否正确。jelly_bean_sb_subscriber的实现如代码3.2所示。
第10-15行:定义write函数,在write函数中调用jelly_bean_scoreboard的check_jelly_bean_taste函数。当jelly_bean_sb_subscriber与jelly_bean_monitor之间的TLM端口连接好之后便可以在monitor一侧调用该write函数,对monitor监测到的彩虹糖信息进行检查。
代码3.2 [class] jelly_bean_sb_subscriber的实现
[Note 1]为什么需要一个$cast?
第11行只声明了jb_sb为jelly_bean_scoreboard类型,而未对其赋值,所以jb_sb是NULL值,无法索引到check_jelly_bean_taste函数。
第13行m_parent是每一个uvm_component所具有的。其是一个uvm_component类型,指向了一个子类对象jelly_bean_scoreboard。由于jb_sb是jelly_bean_scoreboard类型,所以把父类句柄复制给子类句柄时使用$cast来转换,使得jb_sb也可以指向jelly_bean_scoreboard对象,进而索引到check_jelly_bean_taste函数并完成预期的检查功能。
我们通过check_jelly_bean_taste函数来检查monitor监测到的信息是否正确。我们期望DUT即我们的彩虹糖评测员,收到酸的巧克力口味的彩虹糖时会表现出负面评价,收到其他口味的彩虹糖时都给出积极的评价。通过对比DUT的反馈信息和监测到的彩虹糖信息来判断彩虹糖评测员是否给出了正确的评价。如果DUT评价正确,彩虹糖的口味和颜色信息都会被打印出来。当DUT评价错误,错误指示信息会被打印出来。如代码3.3所示是jelly_bean_scoreboard的具体实现。
第4行:在jelly_bean_scoreboard中声明一个uvm_analysis_export用来和jelly_bean_sb_subscriber中的analysis_export相连接进行TLM通信,传输jelly_bean_transaction。
第14行:在jelly_bean_scoreboard中创建了jelly_bean_sb_subscriber。
第19行:在jelly_bean_scoreboard中将创建的uvm_analysis_export和sb_subscriber中的analysis_export连接起来,进行通信。
第21-41行:定义check_jelly_bean_taste函数,实现具体的检查行为。其中定义了一个uvm_table_printer来对jelly_bean_transaction中的内容进行规范化的打印。
代码3.3 [class] jelly_bean_scoreboard的实现
[Note 2] 为什么jelly_bean_scoreboard中使用uvm_analysis_export而不是uvm_analysis_imp?
jelly_bean_scoreboard并不是TLM通信的终点,Monitor监测到的数据需要经过jelly_bean_scoreboard送给jelly_bean_sb_subscriber去做检查,所以jelly_bean_sb_subscriber才是信息传送的终点,其内部的端口才是uvm_analysis_imp。
uvm_subscriber作为jelly_bean_fc_subscriber和jelly_bean_sb_subscriber的基类,其预定义有一个analysisimport被称为analysisexport。uvm_analysis_imp#(T, class_name) analysis_export。
所以jelly_bean_scoreboard中是uvm_analysis_export而jelly_bean_sb_subscriber中是uvm_analysis_imp。
三、UVM环境(Environment)
UVM环境包含了所有创建的验证组件,并在其中完成了各个组件之间的通信端口的连接。UVM环境的具体实现如代码3.4所示。
第14-16行:在env中创建了构建环境的各个组件,包括jelly_bean_agent,jelly_bean_fc_subscriber,jelly_bean_scoreboard。
第21-22行:将jelly_bean_agent中的uvm_analysis_port分别与功能覆盖率收集组件jelly_bean_fc_subscriber和记分板jelly_bean_scoreboard中的analysis_export相连接。便于monitor将监测到的jelly_bean_transaction分别送去分析功能覆盖率以及判断DUT的反馈是否正确。
代码3.4 [class] jelly_bean_env的实现
四、测试用例(Test)
以下测试用例表示的是让彩虹糖工厂生产若干礼品盒装的无糖彩虹糖。该测试用例的具体实现如代码3.5所示。
第19行:使用set_type_override将所有jelly_bean_transaction替换成了sugar_free_jelly_bean_transaction,这样彩虹糖工厂生产出来的彩虹糖都是无糖的。
第20行:在测试用例中创建整个UVM环境jb_env。
第10-22行:为测试用例build_phase的部分。在该build_phase主要完成UVM环境配置文件的传递和基础transaction类型的替换即直接使用无糖彩虹糖配方,最后完成整个UVM环境的创建。
第28行:创建一个礼品盒装的彩虹糖配方即产生一个gift_boxed_jelly_beans_sequence。
第29行:随机礼品盒装彩虹糖的配方内容。
第31行:使用start方式将sequence交由sequencer发送出去。
第27和33行:使用objection机制来控制仿真的停止。在第27行提起一个objection防止仿真结束,在第33行在发送完sequence之后等待10ns撤销objection允许仿真结束。
第24-34行:为测试用例的run_phase部分。主要完成sequence的创建,随机和发送。
代码3.5 [class] jelly_bean_test的实现
五、配置(configuration)
将控制验证平台的各种参数集合在一起构成一个配置块,然后在创建验证平台之前将配置信息传递下去,这样就可以很方便地根据实际情况来配置整个验证平台。如代码3.6所示,是配置块的实现。在本文中,该配置块没有产生任何作用,仅仅是为了方便后续验证平台的复用。
代码3.6 [class] jelly_bean_configuration的实现
六、顶层(Top)
建立好测试用例,搭建好UVM环境之后,还需要建立一个Top模块,在其中例化待测设计,传递interface从而将硬件形式的待测设计和软件形式的验证平台连接起来以及通过run_test来启动uvm仿真。如代码3.7所示是Top模块的具体实现。
第5行:例化一个具有某一时钟频率的interface。
第6行:例化待测设计,并使用interace将其和验证平台连接起来。
第8-12行:产生时钟,为待测设计和验证平台提供100M频率的时钟。
第15-16行:使用uvm_config_db,以virtualinterface的形式将interface传递给验证环境中的各个组件,比如monitor,driver使得其分别可以监测接口上的信号值以及通过接口驱动待测设计。
第17行:使用run_test()来启动UVM仿真。
代码3.7 [module] top的具体实现
七、仿真(Simulation)
如图3.1所示,是运行jelly_bean_test后EDA工具打印出来的部分log。可以看出整个UVM验证平台功能正常,DUT即彩虹糖评测员反馈的信息正确无误。
图3.2 仿真部分log图
八、总结
我们按照开头的图3.1所示的结构搭建了整个UVM验证平台。在前几节,描述了UVM的基本运行过程,简单介绍了其中的一些运行机制。接下来的小节将会更深入的介绍一些例如virtual sequence等的UVM细节。
[彩虹糖带你入门UVM] 第2节 验证组件之Agent ——彩虹糖工厂的小车间