UVM TLM的实现方式

UVM框架采用TLM(Transaction Level Modeling)机制实现组件间的transaction传输,提高复用性和独立性。TLM主要包含put/imp/export/analysis端口、fifo端口和sequencer-driver端口。fifo端口是组件类,提供了put和get等方法。put/imp/export涉及uvm_blocking_put_port和uvm_blocking_put_imp,它们通过reslove_binding函数实现连接。sequencer-driver端口增加了get-next-item等方法。双向端口如master_port/mast_imp和slave_port/slave_imp支持put和get,transport端口通过transport方法实现req和rsp的传输,req和rsp类型可不同。
AI助手已提取文章相关产品:

在UVM 框架中中,组件之间transaction的传输通过TLM机制实现的,这样对组件的复用性以及各个组件之间的独立性带来了极大的好处,想一想如果么有TLM机制,怎么实现transaction的传输呢,可以会使用SV中的mailbox,在两个将要通信的组件之间各个声明一个mailbox句柄,然后在父一层将两个句柄连接在一块,这样如果不仅仅增加了代码量,同时如果在复用的时候,组件通信的关系发生改变,这样子还需要在顶层修改代码,没有做到组件之间的独立性。而是用TLM,只需要在顶层修改连接关系即可。TLM机制说白了就是将之前使用SV的方法封装到一个特定的class中(这也体现了为什么UVM是方法学,他是在SV带的基础上进一步封装)

  1. 在TLM中常用的主要分为3类端口

  (1)put/imp/export/analysis等

(2)fifo端口

(3)sequencer--------driver之间的端口

fifo端口:其中fifo继承与uvm_component,本身就是一个组件类,在组件中实现了需要的方法,比如put方法,get方法等,同时这个类中声明了很多个我们使用的put/imp/export/analysis port等

put/imp/export/:

上图以uvm_blocking_put_port和uvm_blocking_put_imp为例子来讲解一下

首先有两条路径(1)uvm-tlm-ifs->uvm_port_base->uvm_blocking_put_port/uvm_blocking_put_imp

        (2)uvm-component->uvm-port_component_base->uvm_port_component

在uvm_blocking_put_port中重载了put方法,这个put方法调用的是连接到这个port上的uvm_blocking_put_imp的put方法,在uvm_blocking_put_imp也重载了put方法,而uvm_blocking_put_imp中的put方法调用的是imp所在uvm_component父组件的put方法,为什么可以这么使用呢,核心在于在uvm-port-base中有uvm-port-component这个类实例,同时在uvm-port-component中有uvm-port-base这个类实例,相互之间实现了相互调用。

强调一点port端口必须最终要连接到imp上,或者通过export连接到imp上。如果没有的话当port调用put方法时,调用的是imp.put(),这个时候会出现imp为null的情况,会出错。

具体实现port和imp的相互连接方法是在reslove_binding函数中执行的。普通的组件这个函数是空函数,uvm-port-component组件会调用内置的uvm-port-base的同名函数,从而实现port和imp的互联。

sequencer--------driver之间的端口:

sequencer和driver之间的端口类型和上面基本一样,只是需要在sequencer中多实现一些方法,比如get-next-item等。

 

 

  1. 双向端口

主要是mast_port/mast_imp大类,slave_port/slave_imp大类,transport大类

master,slave相对于以上的单向端口比如put/get/get_peek等,本质上仅仅是多重载了一些方法,使得通过一个端口既可以调用put,又可以调用get

Mast_port/mast_imp:内建put,get,peek等方法,在Mast_port端口处调用put(req),同时也可以调用get(rsp)。即一直是initiator,但是可以同时作为transtration的producer和consumer。(通过一个端口接可以解决),相当于put端口,req有initiator产生,rsp由target产生

 

Slave_port/slave_imp: 内建put,get,peek等方法,在Mast_port端口处调用get(req),同时也可以调用put(rsp)。即一直是initiator,但是可以同时作为transtration的producer和consumer。(通过一个端口接可以解决),相当于get端口,req由target产生,rsp由initiator产生

Transport:

Transport_port/transport_imp
这个端口类型和上面的都不太类似,这个端口最终会调用imp组件一侧的transport方法,trasnport方法调用结束以后consumer一侧拿到了req,同时producer一侧拿到了rsp,这个与上面的mast_port/slave_port不一样

Task   transport(itrans req,output otrans rsp)。

 

关于双向端口,具体的实现方式有上面提到的图相似,这里就不说明了。

 

 

双向端口的与单向端口的本质区别在于,req和rsp的transtration类型可以是不一样的。

 

 

 

您可能感兴趣的与本文相关内容

UVM TLM(事务级建模)是验证环境中组件间基于事务(Transaction)通信的核心机制,通过抽象的事务传输(而非信号级交互)提升验证平台的可重用性和仿真效率[^1]。 ### 核心作用 - **抽象通信**:将组件间的数据传输抽象为事务(Transaction),隐藏底层信号时序细节。 - **提升效率**:事务级通信比信号级仿真更快,尤其适用于复杂协议验证。 - **解耦设计**:组件通过标准TLM接口通信,降低模块间耦合,增强复用性[^1]。 ### 端口类型 UVM库提供了事务级接口、端口、导出、imp端口和分析端口。所有这些TLM元素都需要用来发送事务、接收事务以及从一个组件到另一个组件的传输,不同类型的TLM端口都像管道一样用于组件之间的连接。此外,UVM TLM ports and exports还用于在测试平台层次结构的不同级别之间发送事务对象[^2][^3]。 ### 应用场景 由于其抽象通信、提升效率和解耦设计的特点,UVM TLM尤其适用于复杂协议验证,能够有效提高验证平台的可重用性和仿真效率[^1]。 ### 使用示例 在UVM中使用TLM进行组件间通信的简单示例代码如下: ```systemverilog // 定义一个事务类 class my_transaction extends uvm_sequence_item; rand bit [7:0] data; `uvm_object_utils_begin(my_transaction) `uvm_field_int(data, UVM_ALL_ON) `uvm_object_utils_end function new(string name = "my_transaction"); super.new(name); endfunction endclass // 定义一个发送者组件 class my_sender extends uvm_component; uvm_blocking_put_port #(my_transaction) send_port; `uvm_component_utils(my_sender) function new(string name, uvm_component parent); super.new(name, parent); send_port = new("send_port", this); endfunction task run_phase(uvm_phase phase); my_transaction tx; tx = my_transaction::type_id::create("tx"); assert(tx.randomize()); send_port.put(tx); endtask endclass // 定义一个接收者组件 class my_receiver extends uvm_component; uvm_blocking_put_imp #(my_transaction, my_receiver) recv_imp; `uvm_component_utils(my_receiver) function new(string name, uvm_component parent); super.new(name, parent); recv_imp = new("recv_imp", this); endfunction task put(my_transaction t); `uvm_info("RECEIVER", $sformatf("Received data: %h", t.data), UVM_LOW) endtask endclass // 环境类 class my_env extends uvm_env; my_sender sender; my_receiver receiver; `uvm_component_utils(my_env) function new(string name, uvm_component parent); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); sender = my_sender::type_id::create("sender", this); receiver = my_receiver::type_id::create("receiver", this); endfunction function void connect_phase(uvm_phase phase); sender.send_port.connect(receiver.recv_imp); endfunction endclass // 测试类 class my_test extends uvm_test; my_env env; `uvm_component_utils(my_test) function new(string name, uvm_component parent); super.new(name, parent); endfunction function void build_phase(uvm_phase phase); env = my_env::type_id::create("env", this); endfunction endclass module top; import uvm_pkg::*; `include "uvm_macros.svh" initial begin run_test("my_test"); end endmodule ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值