数组打印的全量显示设置
在 UVM 平台中,打印类中的数组时只显示开头和末尾元素、无法全量显示,本质原因是 UVM 打印器(uvm_printer)对数组长度的默认限制。这是 UVM 为了避免长数组打印导致日志冗余而设计的保护机制,具体原因和解决方法如下:
核心原因:UVM 打印器的数组截断机制
UVM 中负责打印的 uvm_printer 类有两个关键参数控制数组显示行为:
- m_max_array_size:默认值通常为 10,表示数组长度超过此值时会触发截断。
- m_num_linear_items:默认值通常为 8,表示截断时保留的首尾元素数量。
当类中的数组长度超过 m_max_array_size 时,UVM 会自动省略中间元素,只显示前 N 个、后 M 个元素,并用 ... 表示省略部分。例如,一个长度为 20 的数组可能被打印为:
my_array: '{1, 2, 3, 4, 5, 6, 7, 8, ..., 13, 14, 15, 16, 17, 18, 19, 20}
具体场景与解决方法
临时全量打印某个数组
如果只需在特定位置全量显示数组,可在打印时通过 sprint() 或 print() 方法指定参数,临时取消长度限制:
// 打印类对象时,指定 max_array_size=0(0 表示无长度限制)
`uvm_info("PRINT_CLASS", my_class.sprint(/*depth=*/-1, /*max_array_size=*/0), UVM_LOW)
// 或直接调用 print() 方法
my_class.print(uvm_default_printer, -1, 0);
- depth=-1:不限制嵌套深度(适用于数组中包含子对象的场景)。
- max_array_size=0:关闭数组长度限制,全量显示所有元素。
全局修改默认配置(永久生效)
如果需要所有数组打印都全量显示,可在 base_test 的 build_phase 中修改全局打印器的参数:
class base_test extends uvm_test;
`uvm_component_utils(base_test)
function void build_phase(uvm_phase phase);
super.build_phase(phase);
// 获取 UVM 全局默认打印器
uvm_printer default_printer = uvm_default_printer;
// 修改数组最大显示长度(0 表示无限制)
default_printer.m_max_array_size = 0;
// 可选:调整截断时保留的首尾元素数量(全量显示时可忽略)
default_printer.m_num_linear_items = 100;
endfunction
endclass
修改后,所有类中的数组打印都会遵循新规则,不再截断。
自定义打印逻辑(灵活控制格式)
如果需要更个性化的显示格式(如每行显示 5 个元素),可在类中重写 do_print() 方法,手动遍历数组打印:
class my_class extends uvm_object;
rand int my_array[]; // 动态数组
`uvm_object_utils_begin(my_class)
`uvm_field_sarray_int(my_array, UVM_DEFAULT) // 注册数组
`uvm_object_utils_end
// 重写 do_print() 手动控制数组打印
virtual function void do_print(uvm_printer printer);
super.do_print(printer);
printer.print_string("my_array (全量显示)", "");
foreach(my_array[i]) begin
// 每行显示 5 个元素,带索引
printer.print_field($sformatf(" [%02d]", i), my_array[i], 32, UVM_DEC);
if((i+1) % 5 == 0) printer.new_line(); // 每 5 个元素换行
end
endfunction
endclass
总结
类中数组打印被截断的根本原因是 UVM 打印器的默认长度限制。通过临时调整打印参数、全局修改配置或自定义 do_print() 方法,均可实现数组的全量显示。根据调试需求选择即可:临时打印适合局部调试,全局配置适合长期全量日志场景,自定义逻辑适合个性化格式需求。