中国有多少个网站,局域网网站怎样做数据库,求个网站这么难吗2022年贴吧,网站模板颜色UVM Factory#xff1a;验证平台的智能生产线
我们要学习UVM中最强大、最核心的特性之一#xff1a;Factory机制。这就像是一个智能的生产线#xff0c;可以根据需求动态更换生产的产品类型#xff0c;而不需要修改生产线本身。
#x1f3af; 一句话理解UVM F…UVM Factory验证平台的智能生产线我们要学习UVM中最强大、最核心的特性之一Factory机制。这就像是一个智能的生产线可以根据需求动态更换生产的产品类型而不需要修改生产线本身。 一句话理解UVM FactoryUVM Factory就像智能汽车生产线原本生产线生产基础车型基类通过配置可以生产豪华版、运动版等各种车型派生类无需改造生产线代码完全不用修改⚡ 为什么需要Factory场景汽车工厂升级想象一个汽车工厂原有产线生产基础轿车base_car新需求需要生产SUVsuv_car、跑车sports_car传统方式需要重新设计生产线成本高昂智能工厂只需调整配置文件同一条生产线就能生产不同车型在UVM中的实际问题协议升级从以太网v1.0升级到v2.0测试变体同一个测试需要测试正常、错误、边界等场景组件替换将普通driver替换为带错误注入的driver Factory工作原理图解先通过一个流程图理解Factory如何动态创建对象 核心概念两种覆盖方式1. 类型覆盖Type Override全局替换所有该类型的实例都会被替换// 方法1通过类型句柄set_type_override_by_type(base_agent::get_type(),child_agent::get_type());// 方法2通过类型名称字符串set_type_override_by_name(base_agent,child_agent);效果整个测试平台中所有的base_agent都会被替换成child_agent2. 实例覆盖Instance Override局部替换只替换特定路径下的实例// 方法1通过类型句柄set_inst_override_by_type(m_env.m_agent,base_agent::get_type(),child_agent::get_type());// 方法2通过类型名称set_inst_override_by_name(base_agent,child_agent,{get_full_name(),.m_env.m_agent});效果只有指定路径下的base_agent会被替换成child_agent 代码深度解析第一步必须的准备工作1. 类必须注册到Factory// 组件类继承自uvm_component使用uvm_component_utils(类名)// 对象类继承自uvm_object使用uvm_object_utils(类名)// 例子class base_agent extends uvm_agent;uvm_component_utils(base_agent)// 必须// ...endclass class child_agent extends base_agent;uvm_component_utils(child_agent)// 必须// ...endclass如果不注册Factory不认识这个类无法进行覆盖2. 必须使用type_id::create()创建对象// ❌ 错误直接使用new()Factory无法介入base_agent m_agentnew(m_agent,this);// ✅ 正确使用type_id::create()Factory可以介入base_agent m_agentbase_agent::type_id::create(m_agent,this);关键只有通过type_id::create()创建的对象Factory才能进行覆盖第二步简单的覆盖示例基类和派生类定义// 基类代理class base_agent extends uvm_agent;uvm_component_utils(base_agent)functionnew(string name,uvm_component parent);super.new(name,parent);endfunction virtual taskrun_phase(uvm_phase phase);uvm_info(AGENT,这是基础代理,UVM_LOW)endtask endclass// 派生类代理class child_agent extends base_agent;uvm_component_utils(child_agent)functionnew(string name,uvm_component parent);super.new(name,parent);endfunction virtual taskrun_phase(uvm_phase phase);uvm_info(AGENT,这是子类代理覆盖后的,UVM_LOW)endtask endclass环境类class base_env extends uvm_env;uvm_component_utils(base_env)base_agent m_agent;// 声明为基类句柄functionnew(string name,uvm_component parent);super.new(name,parent);endfunction virtual functionvoidbuild_phase(uvm_phase phase);super.build_phase(phase);// 关键使用Factory创建对象m_agentbase_agent::type_id::create(m_agent,this);// Factory会检查是否有覆盖配置// 如果有覆盖返回child_agent对象// 如果没有覆盖返回base_agent对象endfunction endclass第三步测试中的覆盖配置测试类配置类型覆盖class type_override_test extends uvm_test;uvm_component_utils(type_override_test)base_env m_env;functionnew(string name,uvm_component parent);super.new(name,parent);endfunction virtual functionvoidbuild_phase(uvm_phase phase);// 1. 先配置覆盖set_type_override_by_type(base_agent::get_type(),child_agent::get_type());// 2. 再创建对象m_envbase_env::type_id::create(m_env,this);endfunction virtual functionvoidend_of_elaboration_phase(uvm_phase phase);// 打印Factory配置调试用uvm_factory::get().print();endfunction endclass输出结果#### Factory Configuration (*) Type Overrides: Requested Type Override Type -------------- ------------- base_agent child_agent ← 类型覆盖生效 UVM_INFO 0: uvm_test_top.m_env.m_agent [AGENT] 这是子类代理覆盖后的 ← 实际运行的是child_agent测试类配置实例覆盖class inst_override_test extends uvm_test;uvm_component_utils(inst_override_test)base_env m_env1,m_env2;functionnew(string name,uvm_component parent);super.new(name,parent);endfunction virtual functionvoidbuild_phase(uvm_phase phase);// 只覆盖m_env1.m_agent不覆盖m_env2.m_agentset_inst_override_by_type(m_env1.m_agent,base_agent::get_type(),child_agent::get_type());// 创建两个环境m_env1base_env::type_id::create(m_env1,this);m_env2base_env::type_id::create(m_env2,this);endfunction endclass输出结果UVM_INFO 0: uvm_test_top.m_env1.m_agent [AGENT] 这是子类代理覆盖后的 ← 被覆盖 UVM_INFO 0: uvm_test_top.m_env2.m_agent [AGENT] 这是基础代理 ← 未被覆盖 类型覆盖 vs 实例覆盖对比特性类型覆盖实例覆盖影响范围全局所有实例局部特定路径配置方法set_type_override_by_type/nameset_inst_override_by_type/name路径参数不需要路径需要完整路径使用场景协议升级全局替换特定组件增强优先级低高可覆盖类型覆盖️ 实际应用协议升级示例场景从以太网v1.0升级到v2.01. 基础数据包v1.0class eth_packet extends uvm_sequence_item;uvm_object_utils(eth_packet)rand bit[47:0]dst_addr;rand bit[47:0]src_addr;rand bit[15:0]eth_type;rand bit[7:0]payload[];functionnew(string nameeth_packet);super.new(name);uvm_info(PKT,创建以太网v1.0数据包,UVM_MEDIUM)endfunction endclass2. 升级版数据包v2.0class eth_v2_packet extends eth_packet;uvm_object_utils(eth_v2_packet)rand bit[31:0]vlan_tag;// 新增VLAN标签rand bit qos_enable;// 新增QoS使能rand bit[2:0]priority;// 新增优先级functionnew(string nameeth_v2_packet);super.new(name);uvm_info(PKT,创建以太网v2.0数据包带VLAN和QoS,UVM_MEDIUM)endfunction endclass3. 驱动程序class eth_driver extends uvm_driver #(eth_packet);uvm_component_utils(eth_driver)eth_packet pkt;virtual functionvoidbuild_phase(uvm_phase phase);super.build_phase(phase);// 使用Factory创建数据包pkteth_packet::type_id::create(pkt);endfunction virtual taskrun_phase(uvm_phase phase);uvm_info(DRIVER,$sformatf(处理数据包类型%s,pkt.get_type_name()),UVM_MEDIUM)endtask endclass4. 测试升级到v2.0class v2_protocol_test extends uvm_test;uvm_component_utils(v2_protocol_test)eth_driver driver;virtual functionvoidbuild_phase(uvm_phase phase);super.build_phase(phase);// 关键只需一行配置所有eth_packet升级为eth_v2_packetset_type_override_by_type(eth_packet::get_type(),eth_v2_packet::get_type());drivereth_driver::type_id::create(driver,this);endfunction endclass优势无需修改driver、monitor、scoreboard等任何组件代码 高级用法复杂覆盖场景场景1部分组件错误注入class error_injection_test extends uvm_test;uvm_component_utils(error_injection_test)virtual functionvoidbuild_phase(uvm_phase phase);super.build_phase(phase);// 1. 正常driver覆盖为错误注入driverset_type_override_by_type(base_driver::get_type(),error_inject_driver::get_type());// 2. 但监控器保持正常// 监控器仍然是base_monitor// 3. 只对agent1的检查器注入错误set_inst_override_by_type(m_env.m_agent1.m_checker,base_checker::get_type(),error_inject_checker::get_type());endfunction endclass场景2多测试变体// 基础测试class base_test extends uvm_test;// 基础配置endclass// 变体1性能测试class perf_test extends base_test;virtual functionvoidbuild_phase(uvm_phase phase);super.build_phase(phase);// 替换为性能监控组件set_type_override_by_type(base_monitor::get_type(),perf_monitor::get_type());endfunction endclass// 变体2覆盖率测试class coverage_test extends base_test;virtual functionvoidbuild_phase(uvm_phase phase);super.build_phase(phase);// 替换为带覆盖率收集的组件set_type_override_by_type(base_monitor::get_type(),coverage_monitor::get_type());endfunction endclass// 变体3错误测试class error_test extends base_test;virtual functionvoidbuild_phase(uvm_phase phase);super.build_phase(phase);// 替换为错误注入组件set_type_override_by_type(base_driver::get_type(),error_inject_driver::get_type());endfunction endclass⚠️ 常见错误和调试技巧错误1忘记注册类// ❌ 错误没有使用uvm_component_utils注册class my_driver extends uvm_driver;// 缺少uvm_component_utils(my_driver)functionnew(string name,uvm_component parent);super.new(name,parent);endfunction endclass// ✅ 正确必须注册class my_driver extends uvm_driver;uvm_component_utils(my_driver)// 必须// ...endclass错误2使用new()而不是create()// ❌ 错误Factory无法介入base_agent agentnew(agent,this);// ✅ 正确Factory可以介入base_agent agentbase_agent::type_id::create(agent,this);错误3覆盖配置顺序错误virtual function void build_phase(uvm_phase phase); // ❌ 错误先创建对象后配置覆盖覆盖无效 m_env base_env::type_id::create(m_env, this); // 创建base_env set_type_override_by_type(...); // 太晚了 // ✅ 正确先配置覆盖后创建对象 set_type_override_by_type(...); // 先配置 m_env base_env::type_id::create(m_env, this); // 后创建 endfunction调试技巧打印Factory配置virtual functionvoidend_of_elaboration_phase(uvm_phase phase);super.end_of_elaboration_phase(phase);// 打印所有Factory配置uvm_factory factoryuvm_factory::get();factory.print();// 或者只打印覆盖配置factory.print_overrides();endfunction输出示例#### Factory Configuration (*) Instance Overrides: Requested Type Override Path Override Type -------------- ------------------------------ ------------- base_driver uvm_test_top.m_env.m_agent0.* spi_driver Type Overrides: Requested Type Override Type -------------- ------------- eth_packet eth_v2_packet调试技巧检查对象类型virtual taskrun_phase(uvm_phase phase);// 检查实际创建的对象类型uvm_info(DEBUG,$sformatf(实际类型%s期望类型%s,m_agent.get_type_name(),// 实际类型child_agent),// 期望类型UVM_LOW)// 使用is()函数检查if(m_agent.is(child_agent))uvm_info(DEBUG,对象是child_agent类型,UVM_LOW)elseuvm_error(DEBUG,对象类型不符合预期)endtask 实战练习建议练习1基础覆盖创建基类base_driver和派生类enhanced_driver在测试中配置类型覆盖验证driver类型是否正确替换练习2实例覆盖创建包含多个相同组件的环境使用实例覆盖只替换其中一个验证只有指定组件被替换练习3复杂场景创建多层级的测试平台配置多级覆盖类型覆盖实例覆盖使用factory.print()查看配置练习4协议升级实现v1.0和v2.0协议数据包使用Factory动态切换协议版本验证所有组件都正确使用新协议 设计模式推荐模式1测试工厂模式// 测试工厂根据配置生成不同测试class test_factory;staticfunction uvm_testcreate_test(string test_name);uvm_test test;case(test_name)normal_test:testnormal_test::type_id::create(test,null);error_test:testerror_test::type_id::create(test,null);// error_test内部会配置错误注入覆盖coverage_test:testcoverage_test::type_id::create(test,null);// coverage_test内部会配置覆盖率收集覆盖default:uvm_fatal(TEST,$sformatf(未知测试%s,test_name))endcasereturntest;endfunction endclass模式2配置数据库Factory组合class configurable_test extends uvm_test;// 从配置数据库获取测试类型virtual functionvoidbuild_phase(uvm_phase phase);string test_mode;// 从配置获取测试模式if(!uvm_config_db#(string)::get(this,,test_mode,test_mode))test_modenormal;// 默认// 根据模式配置覆盖case(test_mode)normal:;// 不配置覆盖error:set_type_override_by_type(base_driver::get_type(),error_inject_driver::get_type());performance:set_type_override_by_type(base_monitor::get_type(),perf_monitor::get_type());endcase endfunction endclass模式3层次化覆盖class hierarchical_override_test extends uvm_test;virtual functionvoidbuild_phase(uvm_phase phase);// 1. 全局类型覆盖低优先级set_type_override_by_type(base_driver::get_type(),enhanced_driver::get_type());// 2. 特定实例覆盖高优先级会覆盖类型覆盖set_inst_override_by_type(m_env.m_agent0.m_driver,base_driver::get_type(),special_driver::get_type());// 3. 更具体的实例覆盖最高优先级set_inst_override_by_type(m_env.m_agent0.m_driver.m_sub_component,base_component::get_type(),custom_component::get_type());endfunction endclass 总结UVM Factory是动态配置、灵活替换的利器核心机制通过覆盖配置动态改变对象类型两种方式类型覆盖全局和实例覆盖局部必要条件类必须注册 使用type_id::create()主要优势提高代码复用支持测试变体简化维护记住黄金法则Factory机制真强大动态替换全靠它类要注册用宏创建对象用create覆盖配置先设置对象创建后执行类型覆盖改全部实例覆盖改局部调试打印看配置对象类型可检查。掌握了Factory机制你就能构建灵活、可扩展的验证平台现在尝试在你的项目中应用Factory体验动态配置的强大功能吧