在uvm环境中extern task
时间: 2024-06-11 10:08:55 浏览: 334
在UVM环境中,extern task是一种在不同组件之间共享任务的方式。它允许一个组件调用另一个组件中定义的任务,而无需在组件之间建立任何通信机制。
使用extern task的步骤如下:
1. 在需要共享任务的组件中,定义一个extern task。
2. 在调用该任务的组件中,声明该extern task。
3. 在需要调用该任务的地方,使用$extern调用该任务。
例如,假设有两个组件A和B,组件A需要调用组件B中的一个任务task_B。可以按照以下步骤实现:
在组件B中定义extern task:
```verilog
class B extends uvm_component;
extern task task_B();
endclass
```
在组件A中声明该extern task:
```verilog
class A extends uvm_component;
extern task task_B();
...
endclass
```
在组件A中调用该任务:
```verilog
task run_phase(uvm_phase phase);
...
$extern(B.task_B());
...
endtask
```
需要注意的是,extern task只能在UVM中的组件中使用,不能在模块或类中使用。此外,调用extern task时,需要注意任务的作用域和访问权限。
相关问题
UVM extern和this
### UVM 中 `extern` 关键字与 `this` 指针
#### 外部声明与实现分离:`extern` 关键字的作用
在UVM框架内,`extern`关键字用于类成员函数的外部声明。这意味着该函数的具体实现在当前文件之外定义,在其他地方完成。这种机制有助于代码组织和维护,使得接口和具体实现可以分开管理[^1]。
```verilog
// 声明部分
class my_class extends uvm_component;
extern function new(string name, uvm_component parent);
endclass : my_class
// 实现部分 (通常位于另一个文件中)
function my_class::new(string name, uvm_component parent);
super.new(name, parent);
// 初始化操作...
endfunction
```
#### 当前实例引用:`this` 指针的应用
`this`指针指向正在执行的方法所属的对象本身。它允许访问对象内部的数据成员和其他方法,并且可以在派生类重载的情况下保持对基类属性的操作一致性。特别是在虚函数调用链路里起到至关重要的作用[^2]。
```verilog
virtual task run_phase(uvm_phase phase);
super.run_phase(phase); // 调用父类版本
$display("Current object's name is %s", this.get_name());
// 这里的 'this' 明确表示当前组件实例
endtask
```
#### 使用场景对比
- **`extern` 的典型应用场景**
对于大型项目而言,将复杂的逻辑拆分成多个源文件能够提高可读性和编译效率。比如在一个验证环境中,如果某个组件具有许多配置选项,则可以通过`extern`把它们移到单独的头文件或C++模板库中处理。
- **`this` 的主要用途**
在继承结构复杂的情形下,利用`this`可以帮助区分局部变量同成员变量之间的冲突;另外,在回调函数注册或是事件监听器设置时也经常需要用到`this`来传递特定上下文环境下的对象实体信息给目标接收者。
class vbase_test extends uvm_test; `uvm_component_utils(vbase_test) env m_env; vseqr m_vseqr; int unsigned simSeed; function new(string name, uvm_component parent); super.new(name, parent); endfunction : new extern function void build_phase (uvm_phase phase); extern function void connect_phase (uvm_phase phase); extern task reset_phase(uvm_phase phase); extern task reset_reg_model(); extern function void end_of_elaboration_phase(uvm_phase phase); extern function void start_of_simulation_phase(uvm_phase phase); extern task main_phase(uvm_phase phase); // report test result extern virtual function void report_phase(uvm_phase phase); endclass : vbase_test function void vbase_test::build_phase (uvm_phase phase); super.build_phase(phase); m_env = env::type_id::create(.name("m_env"), .parent(this)); // virtual sequencer m_vseqr = vseqr::type_id::create(.name("m_vseqr"), .parent(this)); uvm_config_db# (uvm_object_wrapper)::set(this,"m_vseqr.main_phase","default_sequence",vBaseSeq::type_id::get()); //uvm_config_db# (uvm_object_wrapper)::set(this,"m_vseqr.main_phase","default_sequence",vUniBaseSeq#()::type_id::get()); endfunction : build_phase function void vbase_test::connect_phase (uvm_phase phase); m_vseqr.p_rm = m_env.m_reg_model; m_vseqr.i2c_seqr = m_env.m_i2c_agent.m_seqr; endfunction : connect_phase task vbase_test::reset_phase(uvm_phase phase); //`uvm_info(get_type_name(), {"REGISTER MODEL:\n", m_reg_model.sprint()}, UVM_MEDIUM) reset_reg_model(); super.reset_phase(phase); endtask task vbase_test::reset_reg_model(); forever begin wait (tb_top.reset_n == 0); m_env.m_reg_model.reset(); `uvm_info(get_type_name(), "Reseting Complete", UVM_MEDIUM) wait (tb_top.reset_n == 1); end endtask function void vbase_test::end_of_elaboration_phase(uvm_phase phase); int handle; $system("rm -rf TEST_RUNNING"); simSeed = $get_initial_random_seed(); handle = $fopen($psprintf("TEST_RUNNING_%0d",simSeed),"w"); $fclose(handle); handle = $fopen("caseSeed","w"); $fwrite(handle,"%0d",simSeed); $fclose(handle); if($test$plusargs("uvm_tree")) uvm_top.print_topology(); endfunction : end_of_elaboration_phase function void vbase_test::start_of_simulation_phase(uvm_phase phase); `uvm_info(get_type_name(), {"start of simulation for ", get_full_name()}, UVM_HIGH); endfunction : start_of_simulation_phase task vbase_test::main_phase(uvm_phase phase); phase.phase_done.set_drain_time(this, 200ns); endtask : main_phase // report test result function void vbase_test::report_phase(uvm_phase phase); uvm_report_server server; int handle; int unsigned err_num; super.report_phase(phase); server = get_report_server(); err_num = (server.get_severity_count(UVM_ERROR) + server.get_severity_count(UVM_FATAL)); simSeed = $get_initial_random_seed(); $display("\n********************************************************************************************\n"); if (err_num != 0) begin $display("TEST CASE FAILED!!!"); handle = $fopen($psprintf("TEST_FAILED_%0d",simSeed),"w"); end else begin $display("TEST CASE PASSED!!!"); handle = $fopen($psprintf("TEST_PASSED_%0d",simSeed),"w"); end $fclose(handle); $display("\n********************************************************************************************\n"); $system("rm -rf TEST_RUNNING*"); endfunction `endif
这是一个VMM(Verification Methodology Manual)风格的UVM(Universal Verification Methodology)测试类`vbase_test`的实现。以下是对每个函数的简要说明:
- `new`函数:构造函数,用于初始化测试类的成员变量。
- `build_phase`函数:在构建阶段(build phase)创建测试环境(`m_env`)和虚拟序列产生器(`m_vseqr`),并通过UVM配置数据库设置默认的序列(`vBaseSeq`)到虚拟序列产生器。
- `connect_phase`函数:在连接阶段(connect phase)连接虚拟序列产生器的输入端口和测试环境的相关组件。
- `reset_phase`函数:重置阶段(reset phase)的任务,在系统复位信号为低电平时重置寄存器模型(`m_env.m_reg_model`)。
- `reset_reg_model`函数:重置寄存器模型的任务,无限循环等待系统复位信号为低电平,然后调用寄存器模型的重置方法,并在系统复位信号为高电平时完成重置操作。
- `end_of_elaboration_phase`函数:结束实例化阶段(end of elaboration phase)的任务,删除之前运行的测试结果文件,并记录随机种子到文件中。
- `start_of_simulation_phase`函数:开始仿真阶段(start of simulation phase)的任务,用于在仿真开始时打印相关信息。
- `main_phase`函数:主阶段(main phase)的任务,设置阶段完成延迟时间。
- `report_phase`函数:报告阶段(report phase)的任务,用于打印测试结果和清理相关文件。
请注意,这只是一个测试类的简化版本,具体实现可能还包括其他成员变量和方法。如果您有特定的问题或需要进一步的帮助,请提供更多的上下文信息。
阅读全文
相关推荐















