文章目录
- 前言
- 1. `connect_phase` 的作用与执行顺序
- 2. TLM 连接的类型与示例
- 2.1 生产者-消费者模型
- 2.2 分析端口广播模型
- 3. 层次化连接示例
- 4. 动态连接与条件化配置
- 5. 关键注意事项
- 6. 完整示例:SoC 验证环境连接
- 6.1 Monitor 广播数据
- 6.2 Scoreboard 和 Coverage
- 6.3 Env 中的连接
前言
在 UVM 验证环境中,connect_phase
是组件间通信链路构建的核心阶段,用于连接 TLM 端口、分析端口等通信接口。以下是分步骤的详细应用说明:
1. connect_phase
的作用与执行顺序
- 功能:建立组件间的通信通道(如 TLM 端口、分析端口、FIFO 等)。
- 执行顺序:自底向上(Bottom-Up),子组件的
connect_phase
先于父组件执行。 - 与
build_phase
的区别:build_phase
创建组件实例,connect_phase
连接组件实例。
2. TLM 连接的类型与示例
2.1 生产者-消费者模型
场景:Driver 生成事务(Transaction),Scoreboard 接收事务进行比对。
// Driver 类定义(生产者)
class instruction_driver extends uvm_driver #(instruction_tx);`uvm_component_utils(instruction_driver)uvm_blocking_put_port #(instruction_tx) put_port; // 阻塞式输出端口function new(string name, uvm_component parent);super.new(name, parent);put_port = new("put_port", this);endfunction
endclass// Scoreboard 类定义(消费者)
class regfile_scoreboard extends uvm_scoreboard;`uvm_component_utils(regfile_scoreboard)uvm_blocking_put_imp #(instruction_tx, regfile_scoreboard) put_imp; // 阻塞式输入端口实现function new(string name, uvm_component parent);super.new(name, parent);put_imp = new("put_imp", this);endfunction// 实现 put 方法(接收数据)task put(instruction_tx tx);// 比对逻辑endtask
endclass// Env 中的 connect_phase 连接端口
class processor_env extends uvm_env;instruction_driver driver;regfile_scoreboard scoreboard;virtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);driver.put_port.connect(scoreboard.put_imp); // 端口绑定endfunction
endclass
2.2 分析端口广播模型
场景:Monitor 监控 DUT 信号,通过分析端口广播给多个组件(Scoreboard、Coverage)。
// Monitor 类定义(广播者)
class data_monitor extends uvm_monitor;`uvm_component_utils(data_monitor)uvm_analysis_port #(data_tx) ap; // 分析端口function new(string name, uvm_component parent);super.new(name, parent);ap = new("ap", this);endfunctiontask run_phase(uvm_phase phase);// 捕获数据并通过 ap.write(tx) 广播endtask
endclass// Scoreboard 和 Coverage 类定义(订阅者)
class data_scoreboard extends uvm_scoreboard;uvm_analysis_imp #(data_tx, data_scoreboard) ap_imp;function new(string name, uvm_component parent);super.new(name, parent);ap_imp = new("ap_imp", this);endfunctionfunction void write(data_tx tx);// 数据比对逻辑endfunction
endclassclass data_coverage extends uvm_component;uvm_analysis_imp #(data_tx, data_coverage) ap_imp;function new(string name, uvm_component parent);super.new(name, parent);ap_imp = new("ap_imp", this);endfunctionfunction void write(data_tx tx);// 覆盖率收集逻辑endfunction
endclass// Env 中的 connect_phase 连接分析端口
class data_env extends uvm_env;data_monitor monitor;data_scoreboard scoreboard;data_coverage coverage;virtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);monitor.ap.connect(scoreboard.ap_imp); // 单播连接monitor.ap.connect(coverage.ap_imp); // 多播连接endfunction
endclass
3. 层次化连接示例
场景:在 SoC 验证中,连接跨层级的组件(如 Agent 到 Env 级 Scoreboard)。
// Agent 内部定义分析端口
class data_agent extends uvm_agent;data_monitor monitor;uvm_analysis_port #(data_tx) ap; // Agent 级分析端口virtual function void build_phase(uvm_phase phase);super.build_phase(phase);monitor = data_monitor::type_id::create("monitor", this);ap = new("ap", this);endfunctionvirtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);// 将 Monitor 的端口连接到 Agent 的端口monitor.ap.connect(ap);endfunction
endclass// Env 中跨层级连接
class soc_env extends uvm_env;data_agent d_agent;soc_scoreboard soc_sb;virtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);// 连接 Agent 的端口到 Scoreboardd_agent.ap.connect(soc_sb.ap_imp);endfunction
endclass
4. 动态连接与条件化配置
场景:根据测试需求动态启用/禁用某些连接。
// Env 中按条件连接
class dynamic_env extends uvm_env;data_agent d_agent;debug_monitor dbg_mon;bit enable_debug;virtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);// 默认连接d_agent.monitor.ap.connect(scoreboard.ap_imp);// 动态启用调试连接if (enable_debug) begind_agent.monitor.ap.connect(dbg_mon.ap_imp);endendfunction
endclass
5. 关键注意事项
- 执行顺序:
connect_phase
是自底向上执行,确保子组件先连接,父组件后连接。 - 端口类型匹配:连接的端口必须类型兼容(如
uvm_blocking_put_port
必须连接uvm_blocking_put_imp
)。 - 引用层级路径:跨层级连接时需正确引用组件路径(如
agent.monitor.ap
)。 - 避免空指针:确保连接的组件已在
build_phase
中实例化。 - FIFO 连接:若需缓冲数据,可使用
uvm_tlm_fifo
作为中间件:
uvm_tlm_fifo #(data_tx) fifo = new("fifo", this);
monitor.ap.connect(fifo.analysis_export);
scoreboard.ap_imp.connect(fifo.get_ap);
6. 完整示例:SoC 验证环境连接
6.1 Monitor 广播数据
class soc_monitor extends uvm_monitor;uvm_analysis_port #(soc_tx) ap;virtual task run_phase(uvm_phase phase);forever begin// 捕获 DUT 信号生成 soc_txap.write(tx); // 广播事务endendtask
endclass
6.2 Scoreboard 和 Coverage
class soc_scoreboard extends uvm_scoreboard;uvm_analysis_imp #(soc_tx, soc_scoreboard) ap_imp;function void write(soc_tx tx);// 比对事务与预期结果endfunction
endclassclass soc_coverage extends uvm_component;uvm_analysis_imp #(soc_tx, soc_coverage) ap_imp;function void write(soc_tx tx);// 收集覆盖率endfunction
endclass
6.3 Env 中的连接
class soc_env extends uvm_env;soc_monitor monitor;soc_scoreboard scoreboard;soc_coverage coverage;virtual function void connect_phase(uvm_phase phase);super.connect_phase(phase);monitor.ap.connect(scoreboard.ap_imp);monitor.ap.connect(coverage.ap_imp);endfunction
endclass
通过 connect_phase
,UVM 验证环境中的组件能够高效协作,实现事务级数据交互,为验证场景的动态性和可扩展性奠定基础。