2026/1/27 10:40:15
网站建设
项目流程
网站做地域屏蔽,做网站搞笑口号,阿里云做网站需要些什么条件,网站设计的基本步骤和方法UVM Printer#xff1a;从“手动打印”到“自动格式化”的进化
#x1f3af; 课程目标#xff1a;20分钟掌握UVM对象打印的艺术
今天我要教你UVM中最酷的调试工具——uvm_printer。这就像从“手写简历”到“专业排版软件”的进化#xff0c;让你的调试输出变得美观又专业从“手动打印”到“自动格式化”的进化 课程目标20分钟掌握UVM对象打印的艺术今天我要教你UVM中最酷的调试工具——uvm_printer。这就像从“手写简历”到“专业排版软件”的进化让你的调试输出变得美观又专业 第一部分问题的根源——传统打印的痛点传统方式的痛苦经历想象你要记录员工的个人信息// ❌ 传统方式每个类都要自己写打印函数class Employee;string name;intage;string department;intsalary;// 每个类都要写这样的函数functionvoiddisplay();$display(name%s, age%0d, department%s, salary%0d,name,age,department,salary);endfunction endclass class Manager extends Employee;intteam_size;// 子类还要重写而且要调用super.display()functionvoiddisplay();super.display();$display(team_size%0d,team_size);endfunction endclass// 如果再有Manager的子类又要重写...传统方式的问题重复劳动每个类都要写打印函数格式混乱每个人写法不一样维护噩梦修改字段要改多个地方没有层次嵌套对象打印很麻烦️ 第二部分UVM Printer的三种专业格式UVM提供了三种现成的打印格式就像Word的三种视图1. 表格打印机默认—— Excel表格视图---------------------------------------- Name Type Size Value ---------------------------------------- obj my_data - 1013 data integral 8 h5a addr integral 8 h1 format format - 1022 header integral 4 hb footer integral 3 h02. 树形打印机—— 文件夹树状视图obj: (my_data1013) { data: h5a addr: h1 format: (format1022) { header: hb footer: h0 } }3. 线性打印机—— 单行紧凑视图obj: (my_data1013) { data: h5a addr: h1 format: (format1022) { header: hb footer: h0 } }️ 第三部分两种使用方法简单vs灵活方法1使用宏简单快捷推荐// 步骤1用宏注册字段class Employee extends uvm_sequence_item;string name;intage;string department;intsalary;// 使用uvm_field_*宏注册字段uvm_object_utils_begin(Employee)uvm_field_string(name,UVM_ALL_ON)// 注册字符串uvm_field_int(age,UVM_ALL_ON)// 注册整数uvm_field_string(department,UVM_ALL_ON)uvm_field_int(salary,UVM_ALL_ON)uvm_object_utils_end functionnew(string nameEmployee);super.new(name);endfunction// 注意不需要写print()函数endclass// 步骤2直接使用print()方法initial begin Employee empEmployee::type_id::create(emp);emp.name张三;emp.age30;emp.department研发部;emp.salary50000;// 打印自动格式化emp.print();// 使用默认表格打印机emp.print(uvm_default_tree_printer);// 使用树形打印机emp.print(uvm_default_line_printer);// 使用线性打印机end方法2使用do_print()函数灵活控制class Manager extends Employee;intteam_size;bit has_budget_approval;uvm_object_utils(Manager)functionnew(string nameManager);super.new(name);endfunction// 自定义打印函数virtual functionvoiddo_print(uvm_printer printer);// 1. 先打印父类的字段super.do_print(printer);// 2. 添加本类的字段printer.print_int(team_size,team_size,$bits(team_size));// 3. 格式化特殊字段printer.print_string(budget_approval,has_budget_approval?有:无);endfunction endclass️ 第四部分打印机旋钮高级控制UVM Printer提供了丰富的控制选项就像相机的各种设置class PrinterConfigurator;functionvoidconfigure_printer();// 获取默认打印机uvm_table_printer printeruvm_default_table_printer;// 1. 控制显示深度嵌套层次printer.knobs.depth2;// 只显示2层嵌套// 2. 是否显示类型列printer.knobs.type_name0;// 不显示Type列// 3. 是否显示大小列printer.knobs.size0;// 不显示Size列// 4. 缩进控制printer.knobs.indent4;// 缩进4个空格默认2// 5. 显示完整名称包含路径printer.knobs.full_name1;// 显示obj.data而不是data// 6. 十六进制前缀printer.hex_radix0x;// 用0x代替h// 7. 是否显示对象引用IDprinter.knobs.reference0;// 不显示1013这样的ID// 8. 设置最大宽度printer.knobs.max_width120;// 每行最大120字符endfunction endclass 第五部分嵌套对象的处理情况1简单嵌套用宏自动处理class Department;string name;intemployee_count;uvm_object_utils_begin(Department)uvm_field_string(name,UVM_ALL_ON)uvm_field_int(employee_count,UVM_ALL_ON)uvm_object_utils_end endclass class Company;string name;Department dept;// 嵌套对象uvm_object_utils_begin(Company)uvm_field_string(name,UVM_ALL_ON)uvm_field_object(dept,UVM_ALL_ON)// 注意用_object不是_intuvm_object_utils_end functionnew(string nameCompany);super.new(name);deptDepartment::type_id::create(dept);endfunction endclass情况2复杂嵌套自定义控制class ComplexCompany;string name;Department departments[3];// 对象数组uvm_object_utils_begin(ComplexCompany)uvm_field_string(name,UVM_ALL_ON)// 注意数组需要特殊处理uvm_object_utils_end functionnew(string nameComplexCompany);super.new(name);foreach(departments[i])departments[i]Department::type_id::create($sformatf(dept[%0d],i));endfunction virtual functionvoiddo_print(uvm_printer printer);super.do_print(printer);// 手动打印数组foreach(departments[i])begin printer.print_object($sformatf(departments[%0d],i),departments[i]);end endfunction endclass 第六部分实战完整示例示例打印完整的组织结构// 1. 基础员工类用宏class BaseEmployee extends uvm_sequence_item;string id;string name;intage;uvm_object_utils_begin(BaseEmployee)uvm_field_string(id,UVM_ALL_ON)uvm_field_string(name,UVM_ALL_ON)uvm_field_int(age,UVM_ALL_ON|UVM_DEC)uvm_object_utils_end functionnew(string nameBaseEmployee);super.new(name);endfunction endclass// 2. 经理类继承自定义class Manager extends BaseEmployee;intteam_size;BaseEmployee team_members[5];// 管理5个员工uvm_object_utils_begin(Manager)uvm_field_int(team_size,UVM_ALL_ON|UVM_DEC)// 注意数组不在宏中处理uvm_object_utils_end functionnew(string nameManager);super.new(name);foreach(team_members[i])team_members[i]BaseEmployee::type_id::create($sformatf(member_%0d,i));endfunction virtual functionvoiddo_print(uvm_printer printer);// 先打印基类字段super.do_print(printer);// 打印本类字段printer.print_int(team_size,team_size,$bits(team_size),UVM_DEC);// 控制嵌套深度只打印一层printer.knobs.depth1;// 打印数组foreach(team_members[i])beginif(team_members[i]!null)begin printer.print_object($sformatf(team_members[%0d],i),team_members[i]);end end endfunction endclass// 3. 测试代码class PrinterTest extends uvm_test;Manager ceo;uvm_table_printer custom_printer;virtual functionvoidbuild_phase(uvm_phase phase);super.build_phase(phase);// 创建CEO对象ceoManager::type_id::create(ceo);ceo.idCEO001;ceo.name张总裁;ceo.age45;ceo.team_size5;// 创建自定义打印机custom_printernew();configure_printer(custom_printer);endfunction virtual taskrun_phase(uvm_phase phase);phase.raise_objection(this);// 方法1默认打印表格格式uvm_info(TEST, 默认表格打印机 ,UVM_LOW)ceo.print();// 方法2树形打印uvm_info(TEST, 树形打印机 ,UVM_LOW)ceo.print(uvm_default_tree_printer);// 方法3自定义打印机uvm_info(TEST, 自定义打印机 ,UVM_LOW)ceo.print(custom_printer);phase.drop_objection(this);endtask functionvoidconfigure_printer(uvm_table_printer printer);// 精简配置只显示名称和值printer.knobs.size0;// 不显示大小列printer.knobs.type_name0;// 不显示类型列printer.knobs.indent4;// 缩进4个空格printer.knobs.depth2;// 显示2层深度printer.knobs.full_name1;// 显示完整名称printer.hex_radix;// 不使用十六进制前缀endfunction endclass 第七部分输出对比展示默认表格打印机输出---------------------------------------- Name Type Size Value ---------------------------------------- ceo Manager - 1013 id string 3 CEO001 name string 6 张总裁 age integral 32 45 team_size integral 32 5 team_members[0] Employee - 1022 id string 0 name string 0 age integral 32 0 team_members[1] Employee - 1023 ...树形打印机输出ceo: (Manager1013) { id: CEO001 name: 张总裁 age: 45 team_size: 5 team_members[0]: (Employee1022) { id: name: age: 0 } team_members[1]: (Employee1023) { ... } }自定义打印机输出-------------------------- Name Value -------------------------- ceo - ceo.id CEO001 ceo.name 张总裁 ceo.age 45 ceo.team_size 5 ceo.team_members[0] - ...深度控制为2所以只显示一层 第八部分实用调试技巧技巧1条件打印class SmartPrinter;// 只在需要时打印详细信息functionvoiddebug_print(uvm_object obj,bit verbose0);if(verbose)begin// 详细模式用树形打印机显示所有细节uvm_tree_printer printernew();printer.knobs.depth-1;// 显示所有深度obj.print(printer);endelsebegin// 简洁模式用自定义表格打印机uvm_table_printer printernew();printer.knobs.size0;printer.knobs.type_name0;obj.print(printer);end endfunction endclass技巧2打印部分字段class SelectivePrinter extends uvm_printer;// 自定义打印机只打印感兴趣的字段virtual functionvoidprint_field(string name,uvm_object value);// 只打印名字包含id或name的字段if(name.find(id)0||name.find(name)0)begin super.print_field(name,value);end// 其他字段忽略不打印endfunction endclass技巧3实时切换打印机class DynamicPrinterTest extends uvm_test;// 在仿真过程中动态切换打印机virtual taskrun_phase(uvm_phase phase);uvm_object objget_test_object();// 阶段1正常模式表格uvm_info(PHASE,阶段1正常模式,UVM_LOW)obj.print();// 阶段2发现异常切换到详细模式if(check_error())begin uvm_warning(DEBUG,发现异常切换到详细模式)obj.print(uvm_default_tree_printer);end// 阶段3深度调试模式if(need_deep_debug())begin uvm_table_printer debug_printernew();debug_printer.knobs.depth-1;// 无限深度debug_printer.knobs.full_name1;obj.print(debug_printer);end endtask endclass 第九部分快速参考表uvm_field_* 宏类型宏适用类型示例uvm_field_int整数类型uvm_field_int(age, UVM_ALL_ON)uvm_field_string字符串uvm_field_string(name, UVM_ALL_ON)uvm_field_object对象uvm_field_object(dept, UVM_ALL_ON)uvm_field_enum枚举uvm_field_enum(color_t, color, UVM_ALL_ON)uvm_field_array数组uvm_field_array(ids, UVM_ALL_ON)打印机旋钮速查旋钮作用常用值depth打印深度-1无限0顶层11层嵌套size是否显示大小列0不显示1显示type_name是否显示类型列0不显示1显示full_name是否显示完整名称0只显示字段名1显示obj.fieldindent缩进空格数2默认4常用reference是否显示对象ID0不显示1显示2特殊格式打印方法对比方法优点缺点适用场景宏注册简单自动不够灵活90%的常规场景do_print()灵活可控制需要写代码复杂对象特殊需求混合使用兼顾两者稍复杂既有常规字段又有特殊需求 最终总结UVM Printer的使用哲学UVM Printer让你的调试输出从原始数据变成结构化信息传统打印的痛点 每个类都要写打印函数 格式五花八门 难以阅读嵌套结构 ⚙️ 无法控制输出细节 UVM Printer的优势 三种专业格式可选 自动处理继承和嵌套 ️ 丰富的控制选项 一致的输出格式记住这个使用策略简单对象用宏复杂对象用do_print日常调试用表格分析结构用树形紧凑查看用线性默认设置先尝试特殊需求调旋钮。现在你已经掌握了UVM Printer的所有技巧在你的下一个项目中新类设计使用宏注册字段一劳永逸调试阶段根据需求切换不同打印机问题定位使用深度控制和过滤器团队协作统一打印机配置保持日志一致你会发现专业的打印输出能让调试效率提升数倍