本页内容
自定义打印、比较与录制:检查策略状态和输出
日志/调试变化 其他行为变化
影响范围
自定义 printer/comparer/recorder,或将打印和比较日志作为 golden 。
具体差异
操作改由对应 policy 驱动;sprint、compare、copy 在 active depth 为 0 时执行各自 flush,不能推广为所有 recorder 调用均自动清理。自定义 policy 要核对新调用契约。默认策略建议经 set_default/get_default 访问;默认 printer 仍为 table printer,但内部行模型与格式生成已重写,文本黄金文件必须重新对照,不能假定输出逐字相同。
修改方案
保留业务 do_print/do_compare/do_record 钩子;其中调用的 printer/comparer/recorder API 分别按 M02-003 / M02-005 / M02-007 / M02-012 改写。每次独立对象操作核对策略状态,消息过滤按实际 comparer 发出的 MISCMP 路径配置;用返回值、输出内容和字段调用次数验证,不能只按日志数量判定成功。
兼容措施与范围 :业务 do_* 钩子可保留,其策略状态和报告行为仍按目标接口核对;packer 的部分兼容见 M02-001 。
迁移后验证
连续操作两个对象,检查状态没有串扰;同时比较返回值、输出内容和记录次数。不要把 recorder 当成与 sprint 相同的自动 flush 契约。
记录本条结果 :M01-009 · 状态与证据 。
已有实测与复现
补充查阅
扫描定位与记录结果
有扫描规则,覆盖部分可识别写法 。脚本检查名称、参数和部分 FLAG 表达式,并对少数直接声明关联使用点;未做完整类型解析或预处理,行为结果仍需验证。
uv run tools/uvm_migration_scan.py <SoC代码目录> --rules S27
核对命中对象及生效分支后,在条目清单记录修改与验证证据;扫描规则记录用于整理命中位置。
扫描器下载、输入范围与报告说明
源码与标准依据
核查方式:源码与实测核对 。实测仅覆盖本条所列场景。
VCS 内置 UVM-1.2 :uvm_object.svh:913 (print 对 uvm_default_printer==null 报 NULLPRINTER error,经 printer.knobs.mcd 输出)、uvm_object.svh:1120 (compare 内直接报 MISCMP info)、uvm_object.svh:1350 (record 内经 __m_uvm_field_automation(UVM_RECORD) 驱动)
VCS 内置 uvm-ieee-2020-2.0 :uvm_object.svh:873–874 (uvm_printer::get_default() + printer.get_file(),NULLPRINTER 检查移除)、uvm_object.svh:884 (sprint 顶层先 printer.flush())、uvm_object.svh:992 (compare 委托 comparer.compare_object(),缺省 comparer 改由 uvm_comparer::get_default())、uvm_object.svh:1178 (record 委托 recorder.record_object(get_name(), this))
引用代码(高亮为引用行);上方行号链接可直接定位。
src/vcs-uvm-1.2/base/uvm_object.svh if ( printer == null )
printer = uvm_default_printer ;
if ( printer == null )
`uvm_error ( "NULLPRINTER" , "uvm_default_printer is null" )
$ fwrite ( printer . knobs . mcd , sprint ( printer ));
endfunction
// sprint
// ------
function string uvm_object :: sprint ( uvm_printer printer = null );
bit p ;
if ( printer == null )
printer = uvm_default_printer ;
// not at top-level, must be recursing into sub-object
if ( ! printer . istop ()) begin
src/vcs-uvm-1.2/base/uvm_object.svh end
else begin
comparer . print_msg_object ( this , rhs );
uvm_report_info ( "MISCMP" ,
$ sformatf ( "%0d Miscompare(s) for object %s@%0d vs. null" ,
comparer . result ,
__m_uvm_status_container . scope . get (),
this . get_inst_id ()),
__m_uvm_status_container . comparer . verbosity );
done = 1 ;
end
end
if ( ! done && comparer . compare_map . exists ( rhs )) begin
if ( comparer . compare_map [ rhs ] != this ) begin
comparer . print_msg_object ( this , comparer . compare_map [ rhs ]);
end
done = 1 ; //don't do any more work after this case, but do cleanup
end
src/vcs-uvm-1.2/base/uvm_object.svh __m_uvm_status_container . recorder = recorder ;
recorder . recording_depth ++ ;
__m_uvm_field_automation ( null , UVM_RECORD , "" );
do_record ( recorder );
recorder . recording_depth -- ;
//if(recorder.recording_depth==0) begin
// recorder.tr_handle = 0;
//end
endfunction
// do_record (virtual)
// ---------
function void uvm_object :: do_record ( uvm_recorder recorder );
return ;
完整源码 · SHA256:5bacc747c3d5a16a0206864bd84eedf1aeff153a7152dcb0d0e40af208fbe4ec
src/vcs-uvm-ieee-2020-2.0/base/uvm_object.svh // -----
function void uvm_object :: print ( uvm_printer printer = null );
if ( printer == null ) printer = uvm_printer :: get_default ();
$ fwrite ( printer . get_file (), sprint ( printer ));
endfunction
// sprint
// ------
function string uvm_object :: sprint ( uvm_printer printer = null );
string name ;
if ( printer == null ) printer = uvm_printer :: get_default ();
if ( printer . get_active_object_depth () == 0 ) begin
printer . flush () ;
name = printer . get_root_enabled () ? get_full_name () : get_name ();
end
else begin
name = get_name ();
end
printer . print_object ( name , this );
return printer . emit ();
endfunction
src/vcs-uvm-ieee-2020-2.0/base/uvm_object.svh if ( comparer == null ) comparer = uvm_comparer :: get_default ();
if ( comparer . get_active_object_depth () == 0 )
comparer . flush () ;
compare = comparer . compare_object ( get_name (), this , rhs );
endfunction
// do_compare
// ----------
function bit uvm_object :: do_compare ( uvm_object rhs ,
uvm_comparer comparer );
return 1 ;
endfunction
// __m_uvm_field_automation
// ------------------
src/vcs-uvm-ieee-2020-2.0/base/uvm_object.svh if ( recorder == null )
return ;
recorder . record_object ( get_name (), this );
endfunction
// do_record (virtual)
// ---------
function void uvm_object :: do_record ( uvm_recorder recorder );
return ;
endfunction
// m_get_report_object
// -------------------
function uvm_report_object uvm_object :: m_get_report_object ();
完整源码 · SHA256:53c99f38f1ce6cb3c6a215858b84938d18eb858f9396d3dba281a32addb3c9c9
术语解释 · 兼容配置
pack 位流格式改变(M02-001) · 删除无效的打印宽度配置(M02-003) · 自定义比较(M02-005) · 自定义 recorder 的对象递归与文本输出(M02-007) · 重写 recorder、stream、database 方法时同步句柄类型(M02-012)
返回Object / Factory · 迁移清单
版本适用范围