【UVM入门笔记(二)】核心基类_phase机制_config机制_消息管理

1.核心基类(uvm_object)
  • UVM的类最初都是从uvm_void(虚类)继承而来,继承于uvm_void的两个子类为uvm_objectuvm_port_base
  • uvm_object的核心方法主要提供与数据操作相关的服务:copy、clone、compare、print、pack/unpack。
  • 域的自动化。使得注册UVM类的同时可以声明会参与到上述copy等操作的成员变量。
`uvm_object_utils_begin(class_name)
  `uvm_field_int(xx, UVM_ALL_ON)
  `uvm_field_enum(e_class, e_inst, UVM_ALL_ON)
  `uvm_field_string(xx, UVM_ALL_ON)
`uvm_object_utils_end
1)拷贝
  • copy默认已经创建好了对象,只需对数据进行拷贝;clone则会自动创建对象并进行数据拷贝再返回目标对象的句柄。如果成员包括句柄,则拷贝时会额外创建新的对象,将句柄指向该对象。
  • 在执行拷贝时默认进行的是深拷贝,即会执行copy()do_copy()【回调函数】
2)比较
  • 默认的比较器最大输出的错误比较信息为1,即只要发生错误就不会进行后续的比较。
  • uvm_default_comparer.show_max=xx可以更改最大输出的错误比较信息。
  • 实际上,默认情况 下uvm_pkg中例化了很多相关的全局数据操作配置成员,如uvm_default_printeruvm_default_packer
3)打印
  • uvm_default_printer为默认的打印设置,指向了uvm_default_table_printer
  • 其余还有uvm_default_tree/line_printer
  • 如果用户自定义一些打印属性则可通过修改uvm_printer::knob中的成员来定制打印格式。
4)打包和解包
  • pack将自动化声明后的域打包成比特流。
  • unpack与pack相反。将串行数据解包变为原有各自的域。
  • UVM环境中较少使用,但当与外界环境例如SystemC发生大规模数据传递或者UVM与FPGA emulator之间进行数据交换时,该方法则可能会用到。
2.phase机制
  • UVM在验证环境构建时引入phase机制,清晰地将UVM仿真阶段层次化
phase函数/任务执行顺序
build函数自顶向下
connect函数自底向上
end_of_elaboration函数自底向上
start_of_simulation函数自底向上
run任务自底向上
extract函数自底向上
check函数自底向上
report函数自底向上
final函数自顶向下
  • 只有uvm_component及其继承于uvm_component的子类,才会按照phase机制将上面的九个phase先后执行完毕。
  • 其中只有run_phase是task(可以完成一些等待、激励、采样等耗时的任务);build_phase和final_phase的执行顺序为自顶向下,其余的均为自底向上。仿真实例如下:
    在这里插入图片描述
  • run_phase又对应于12个分支phase(并行关系)。pre/-/post_reset/config/main/shutdown
1)UVM编译和运行顺序
  • 在加载硬件模型调用仿真器之前,需完成编译和建模阶段。
  • 在开始仿真之前,分别执行硬件的always/initial语句、UVM的调用测试方法run_test()和run_phase之前的几个phase。
  • 开始仿真后,执行run_phase()或者对应细分的12个phase。
  • 结束仿真后,执行剩余的extract、report等phase。
2)UVM仿真开始
  • 通过由uvm_pkg提供的全局函数run_test()来指定运行哪一个uvm_test,指定的test将被例化并指定为顶层的组件。一般而言,run_test()可以在合适的module/program中调用。
  • 用户也可通过在仿真时传递参数+UVM_TESTNAME=<test_name>来指定仿真时调用的uvm_test
3)UVM世界的“诞生”
  • UVM顶层类uvm_root继承于uvm_component,提供了run_test()等方法作为UVM世界的核心角色。
  • uvm_pkg中有且只有1个uvm_root所例化的对象即uvm_top。通过uvm_top调用run_test(test_name)涉及如下初始化过程:
    ①获取正确的test_name
    ②初始化objection机制
    ③创建uvm_test_top实例
    ④调用phase控制方法
    ⑤等待所有phase执行结束
    ⑥报告总结和结束仿真
3)UVM仿真结束
  • 利用objection挂起机制控制仿真结束。uvm_objection类提供了一种供所有component和sequence共享的计数器。
task run_phase(uvm_phase phase);
  `phase.raise_objection(this);
  ...
  `phase.drop_objection(this);
endtask
  • 如果进入run_phase()后并没有马上挂起objection,则不会继续运行run_phase()而是转入extract_phase()。
3.config机制
  • UVM提供uvm_config_db配置类,可以传递①virtual interface,②单一变量值,③配置对象(config object)。
uvm_config_db#(T)::set(uvm_component cntxt, string inst_name, string field_name, T value);
uvm_config_db#(T)::get(uvm_component cntxt, string inst_name, string field_name, inout T value);
1)interface传递
  • 接口传递需要在run_test()之前,保证在进入build_phase之前virtual interface已经被传递到了uvm_config_db中。
uvm_config_db#(virtual uvm_config_if)::set(uvm_root::get(), "uvm_test_top.*", "vif", if0); //initial块中  root句柄,实例,变量名
uvm_config_db#(virtual uvm_config_if)::get(this, "", "vif", vif);
2)单一变量传递
uvm_config_db#(int)::set(this, "c1", "var1", 10);
uvm_config_db#(int)::get(this, "", "var1", var1);
3)object传递
  • 可以将每个组件的变量加以整合,放置到uvm_object中再进行传递。
uvm_config_db#(uvm_object)::set(this, "c1", "cfg", cfg1);  //父类句柄指向子类
...
uvm_config_fb#(uvm_object)::get(this, "", "cfg", tmp);
void'($cast(cfg, tmp));  //note 父类句柄转到子类实例
4)总结
  • 使用set()/get()方法时传递的参数应该上下保持一致,否则需使用$cast()完成类型转换。
  • 应尽量确保set方法在相关配置组件创建前调用,这是因为只有先完成配置,相关组件在例化前可以得到配置值进而正确地例化。
  • 传递的参数可以使用*通配符来表示任意的层次。
4.消息管理
1)消息方法
function void uvm_report_info(string id, string message, int verbosity = UVM_MEDIUM, string filename = "", int line = 0);
function void uvm_report_warning(string id, string message, int verbosity = UVM_MEDIUM, string filename = "", int line = 0);
function void uvm_report_error(string id, string message, int verbosity = UVM_LOW, string filename = "", int line = 0);
function void uvm_report_fatal(string id, string message, int verbosity = UVM_NONE, string filename = "", int line = 0);
  • 其中verbosity冗余度于消息处理中的过滤直接相关。冗余度的设置如果低于过滤的开关,那么该消息会打印出来,否则不会被打印出来。重要程度由高到低依次为UVM_NONE/LOW/MEDIUM/HIGH/FULL/DEBUG
2)消息处理
  • 消息处理的方式是同消息的严重级别对应的。当然用户也可自定义的修改。
严重级别默认处理方式
UVM_INFOUVM_DISPLAY
UVM_WARNINGUVM_DISPLAY
UVM_ERRORUVM_DISPLAY / UVM_COUNT
UVM_FATALUVM_DISPLAY / UVM_EXIT
  • 此外还有NO_ACTIONUVM_LOGUVM_CALL_HOOKUVM_STOP等处理方式。
3)消息机制
  • 可以通过uvm_report_object类提供的方法自定义配置消息处理方式。该类是间于uvm_object类与uvm_component类之间的中间类,主要功能是完成消息的打印和管理。
  • 消息处理是由uvm_report_handler类来完成的,每个uvm_report_object类中都有一个handler实例。
  • 所有uvm_report_handler实例也都依赖于uvm_pkg中的uvm_report_server唯一实例,但该实例并没有作为全局变量直接暴露给用户,需要通过uvm_report_server::get_server()自行调用。
4)回调函数
  • report_hook()函数通过结合消息处理时的UVM_CALL_HOOK参数,结合用户自定义的回调函数实现不同的配置。
  • 调用回调函数时首先调用report_hook()函数,然后按照severity级别来选择更细致的回调函数report_SEVERITY_hook()
//build phase
set_report_severity_action(UVM_ERROR, UVM_DISPLAY | UVM_CALL_HOOK);
set_report_verbosity_level_hier(UVM_LOW);
//run phase
uvm_report_error("RUN", "error1", UVM_LOW);
//control top
uvm_root::get().set_report_id_verbosity_hier("BUILD", UVM_NONE);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值