UVM使用带参数宏定义sequence时uvm_object_utils工厂注册问题
问题原因
SystemVerilog 预处理器的字符串化操作符"不会自动展开其内部嵌套的宏,而UVM原生的uvm_object_utils宏内部正是直接用字符串化操作符处理传入的参数,因此当你传入SEQ_NAME(abc)时,注册名就被直接定为字符串"SEQ_NAME(abc)",而不是展开后的"abc_test_seq"。
解决方案
不需要修改你当前通过SEQ_NAME宏定义派生类的写法,只需要新增一层辅助宏让参数先完成展开再做字符串化即可,具体实现步骤如下:
- 先定义两个辅助宏,用来处理宏展开优先级问题
// 第一层:字符串化宏 `define STR(arg) `"arg`" // 第二层:支持参数预展开的UVM对象注册宏 `define UVM_UTILS_EXPAND(type) \ typedef uvm_object_registry #(type, `STR(type)) type_id; \ static function type_id get_type(); \ return type_id::get(); \ endfunction \ virtual function uvm_object_wrapper get_object_type(); \ return get_type(); \ endfunction \ virtual function string get_type_name(); \ return `STR(type); \ endfunction
- 替换原有派生类中的注册宏
class `SEQ_NAME(abc) extends base_sequence; // 把原来的`uvm_object_utils(`SEQ_NAME(abc))替换为下面的宏 `UVM_UTILS_EXPAND(`SEQ_NAME(abc)) // 其余原有代码保持不变 ...... endclass
修改完成后,工厂注册名就会变成展开后的"abc_test_seq",你就可以直接使用最初的覆盖语句:
factory.set_type_override_by_name("base_sequence","abc_test_seq");
补充说明
如果你不想自定义注册宏,也可以直接在注册时显式调用uvm对象注册方法,手动传入展开后的字符串,写法如下:
class `SEQ_NAME(abc) extends base_sequence; typedef uvm_object_registry#(`SEQ_NAME(abc), `"`SEQ_NAME(abc)`") type_id; `uvm_object_utils_begin(`SEQ_NAME(abc)) `uvm_object_utils_end ...... endclass
内容的提问来源于stack exchange,提问作者herbert.x
相关产品推荐
相关产品推荐

