抽象和具体class的连接

An alternative to using a virtual interface handle for DUT to UVM testbench connections is to use an abstract concrete class pair. The abstract version of the class defines templates for all the methods that are available in the BFM. The concrete version of the class is declared in the BFM and it extends the abstract version, providing an implementation of the methods. The handle of the concrete class is assigned to the abstract handle in the agent classes via the uvm_config_db. The properties of class object polymorphism allow the abstract class handle to interact with the BFM using the method implementations in the concrete version of the class.

If a class is defined inside an interface or a module, it can reference any of the variables within the interface or module scope. This can be used to simplify the handling of parameters.

The following code snippets show the Abstract and Concrete versions of the sfr_master class:

// The abstract class for the SFR master driver/BFM
class sfr_master_abstract;
 
virtual task execute(sfr_seq_item item);
 
endtask
 
endclass
 
// The implementation for the SFR master BFM, containing the concrete implementation of the sfr_master
module sfr_master_bfm #(ADDR_WIDTH = 8,
DATA_WIDTH = 8)
(input clk,
input reset,
output logic[ADDR_WIDTH-1:0] address,
output logic[DATA_WIDTH-1:0] write_data,
input logic[DATA_WIDTH-1:0] read_data,
output logic we,
output logic re);
 
import uvm_pkg::*;
import sfr_agent_pkg::*;
 
always @(reset or posedge clk) begin
if(reset == 1) begin
re <= 0;
we <= 0;
address <= 0;
write_data <= 0;
end
end
 
// Definition of the concrete version of the sfr_master class:
class sfr_master_concrete extends sfr_master_abstract;
 
task execute(sfr_seq_item item);
if(reset == 1) begin
wait(reset == 0);
end
else begin
@(posedge clk);
address = item.address;
we <= item.we;
write_data <= item.write_data;
re <= item.re;
@(posedge clk);
if(re == 1) begin
item.read_data = read_data;
re <= 0;
end
we <= 0;
end
endtask: execute
endclass
 
// Declaration of the SFR_MASTER class handle
sfr_master_concrete SFR_MASTER;
 
// Initial block, constructing the SFR_MASTER object and assigning the handle into the uvm_config_db
// Note the use of the sfr_master_abstract handle as the uvm_config_db parameter
initial begin
SFR_MASTER = new();
uvm_config_db #(sfr_master_abstract)::set(null, "uvm_test_top", "SFR_MASTER", SFR_MASTER);
end
 
endmodule: sfr_master_bfm

Note that in the above code, the BFM has been changed to a module from an interface, this is another freedom that using the abstract-concrete pattern enables. Modules allow the BFM to have hierarchy.

Inside the SFR agent classes, any reference to the BFM is via handles of the sfr_master_abstract type:在agent中,使用抽象类

class sfr_driver extends uvm_driver #(sfr_seq_item);
 
// Abstract version of the sfr_master class:
sfr_master_abstract SFR;
 
extern task run_phase(uvm_phase phase);
 
endclass: sfr_driver
 
task sfr_driver::run_phase(uvm_phase phase);
sfr_seq_item item;
 
forever begin
seq_item_port.get_next_item(item);
SFR.execute(item);
seq_item_port.item_done();
end
 
endtask: run_phase

The handle to the sfr_master_abstract object is passed via the agent config object via the uvm_config_db, note that in the following code snippet, the sfr_monitor uses the same connection pattern:

class sfr_test extends uvm_component;
 
 
sfr_env_config env_cfg;
sfr_config_object sfr_agent_cfg;
 
sfr_env env;
 
extern function void build_phase(uvm_phase phase);
extern task run_phase(uvm_phase phase);
 
endclass: sfr_test
 
function void sfr_test::build_phase(uvm_phase phase);
env_cfg = sfr_env_config::type_id::create("env_cfg");
sfr_agent_cfg = sfr_config_object:: type_id::create("sfr_agent_cfg");
 
// Assigning the handle to the concrete implementations of the sfr_master and sfr_monitor classes to their abstract counterparts
if(!uvm_config_db #(sfr_master_abstract)::get(this, "", "SFR_MASTER", sfr_agent_cfg.SFR_MASTER)) begin
`uvm_error("BUILD_PHASE", "Unable to find virtual interface sfr_master_bfm in the uvm_config_db")
end
if(!uvm_config_db #(sfr_monitor_abstract)::get(this, "", "SFR_MONITOR", sfr_agent_cfg.SFR_MONITOR)) begin
`uvm_error("BUILD_PHASE", "Unable to find virtual interface sfr_master_bfm in the uvm_config_db")
end
 
sfr_agent_cfg.is_active = 1;
env_cfg.sfr_agent_cfg = sfr_agent_cfg;
env = sfr_env::type_id::create("env", this);
env.cfg = env_cfg;
endfunction: build_phase

When the abstract-concrete class connection pattern is used, the agent does not have to be parameterised, since class handles are used to make the connection.

In summary, the abstract concrete class approach works by passing a class object handle from the hdl_top part of the testbench to the UVM testbench.

最新文章

  1. JavaScript 开发的45个经典技巧
  2. iOS7 和 iOS6的页面兼容问题
  3. IIS 分析器错误消息: 未能加载类型“_Default”
  4. python中的类和实例
  5. 虚拟光驱 DAEMON Tools Lite ——安装与入门
  6. Ubuntu之网络配置
  7. ADO.NET(一)
  8. ibatis的动态sql
  9. JavaScript字符串处理
  10. JAVA不可变类(immutable)机制与String的不可变性
  11. 检测版本更新,iOS
  12. Mac 电脑 开发环境Idea环境搭建
  13. testrem
  14. 实验吧—隐写术——WP之 我喜欢培根
  15. Nginx的ip_hash指令
  16. ubuntu16.04更新源的时候显示:由于没有公钥,无法验证下列签名: NO_PUBKEY 3D5919B448457EE0【学习笔记】
  17. 20155214曾士轩 2016-2017-2 《Java程序设计》第1周学习总结
  18. 12306GT多线程、分流免费抢票工具使用心德
  19. [Codeforces #190] Tutorial
  20. Java应用程序

热门文章

  1. jsp页面动态获取系统时间
  2. Docker系列(6)- 常用命令(2) | 镜像命令
  3. 搭建http文件服务器 - Windows使用IIS搭建http文件服务器
  4. 接口Mock测试
  5. 51nod1676-无向图同构【乱搞】
  6. oracle常见命令
  7. 踩坑系列《十二》解决连接云服务器的redis失败
  8. FastAPI(62)- FastAPI 部署在 Docker
  9. Sentry 监控 - Snuba 数据中台架构简介(Kafka+Clickhouse)
  10. 日常学习用到的Git指令