基于双层优化的微电网系统规划设计方法附Matlab代码
2026/6/20 0:31:31
我们要学习UVM中最强大、最核心的特性之一:Factory机制。这就像是一个智能的生产线,可以根据需求动态更换生产的产品类型,而不需要修改生产线本身。
UVM Factory就像智能汽车生产线:
想象一个汽车工厂:
在UVM中的实际问题:
先通过一个流程图理解Factory如何动态创建对象:
全局替换:所有该类型的实例都会被替换
// 方法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_agent
局部替换:只替换特定路径下的实例
// 方法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
// 组件类(继承自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不认识这个类,无法进行覆盖!
// ❌ 错误:直接使用new(),Factory无法介入base_agent m_agent=new("m_agent",this);// ✅ 正确:使用type_id::create(),Factory可以介入base_agent m_agent=base_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 endclassclass 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_agent=base_agent::type_id::create("m_agent",this);// Factory会检查是否有覆盖配置// 如果有覆盖,返回child_agent对象// 如果没有覆盖,返回base_agent对象endfunction endclassclass 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_env=base_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_agentclass 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_env1=base_env::type_id::create("m_env1",this);m_env2=base_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] 这是基础代理 ← 未被覆盖| 特性 | 类型覆盖 | 实例覆盖 |
|---|---|---|
| 影响范围 | 全局,所有实例 | 局部,特定路径 |
| 配置方法 | set_type_override_by_type/name | set_inst_override_by_type/name |
| 路径参数 | 不需要路径 | 需要完整路径 |
| 使用场景 | 协议升级,全局替换 | 特定组件增强 |
| 优先级 | 低 | 高(可覆盖类型覆盖) |
class 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 name="eth_packet");super.new(name);`uvm_info("PKT","创建以太网v1.0数据包",UVM_MEDIUM)endfunction endclassclass 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 name="eth_v2_packet");super.new(name);`uvm_info("PKT","创建以太网v2.0数据包(带VLAN和QoS)",UVM_MEDIUM)endfunction endclassclass 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创建数据包pkt=eth_packet::type_id::create("pkt");endfunction virtual taskrun_phase(uvm_phase phase);`uvm_info("DRIVER",$sformatf("处理数据包类型:%s",pkt.get_type_name()),UVM_MEDIUM)endtask endclassclass 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());driver=eth_driver::type_id::create("driver",this);endfunction endclass优势:无需修改driver、monitor、scoreboard等任何组件代码!
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// 基础测试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// ❌ 错误:没有使用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// ❌ 错误:Factory无法介入base_agent agent=new("agent",this);// ✅ 正确:Factory可以介入base_agent agent=base_agent::type_id::create("agent",this);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); // 后创建 endfunctionvirtual functionvoidend_of_elaboration_phase(uvm_phase phase);super.end_of_elaboration_phase(phase);// 打印所有Factory配置uvm_factory factory=uvm_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_packetvirtual 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)else`uvm_error("DEBUG","对象类型不符合预期!")endtaskbase_driver和派生类enhanced_driverfactory.print()查看配置// 测试工厂,根据配置生成不同测试class test_factory;staticfunction uvm_testcreate_test(string test_name);uvm_test test;case(test_name)"normal_test":test=normal_test::type_id::create("test",null);"error_test":test=error_test::type_id::create("test",null);// error_test内部会配置错误注入覆盖"coverage_test":test=coverage_test::type_id::create("test",null);// coverage_test内部会配置覆盖率收集覆盖default:`uvm_fatal("TEST",$sformatf("未知测试:%s",test_name))endcasereturntest;endfunction endclassclass 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_mode="normal";// 默认// 根据模式配置覆盖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 endclassclass 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 endclassUVM Factory是"动态配置、灵活替换"的利器:
记住黄金法则:
Factory机制真强大,动态替换全靠它;
类要注册用宏,创建对象用create;
覆盖配置先设置,对象创建后执行;
类型覆盖改全部,实例覆盖改局部;
调试打印看配置,对象类型可检查。
掌握了Factory机制,你就能构建灵活、可扩展的验证平台!现在尝试在你的项目中应用Factory,体验动态配置的强大功能吧!