目录
10. 通信
TLM通信
系统原型,芯片验证
- 作用:更快实现硬件原型之间/验证组件之间的数据通信
- 将模块内的计算和模块之间的通信从时间跨度方面剥离开
- 条件:需要两个通信的对象
- initiator:发起通信请求
- target:发起通信的响应方
- 按照transaction的流向可以分为producer和consumer
- 用户需要将tlm在target一端中实现,便于initiator以后调用target的通信方法
- 最后,在更高层次中连接两个对象,在两个对象中创建TLM端口
- 步骤:
- 分辨initiator和target,分辨producer和consumer
- 在target中实现TLM通信方法
- 在两个对象中创建TLM端口
- 在更高层次将两个对象的端口进行连接
- 数据流向分为单向和双向。单向只有initiator发出req,双向还有target发出rsp返回给initiator
- 端口分为:
- port:initiator的发起端
- export:中间层次的端口
- imp:target接受req的末端,imp的连接无法再次延伸
- 单双向*端口类型
- uvm_void
- uvm_port_base
- uvm_UNDIR_port #(trans_t)
- uvm_UNDIR_export #(trans_t)
- uvm_UNDIR_imp #(trans_t, imp_parent_t)
- uvm_BIDIR_port #(req_trans_t, rsp_trans_t)
- uvm_BIDIR_export #(req_trans_t, rsp_trans_t)
- uvm_BIDIR_imp #(req_trans_t, rsp_trans_t, imp_parent_t)
- uvm_port_base
- uvm_void
端口声明
- 单向端口声明(前3个)
- 声明port和export作为req的发起方,指定trans类型
- 声明imp作为req的接收方,指定trans类型+parent指定所在的组件类型
- 双向端口声明(后3个):trans拆成req和rsp
对应关系
- initiator例化port,中间层次例化export,target例化imp
- 多个port可以连到同一个export或imp,反之就不行,一个port或export不能连到多个imp(traget)
- req的起点是port,终点是imp,中间可以穿越多个层次,但是建议在穿越的层次中声明export
- port可任意连接;export不能连接port;imp只能作为终点,无法扩展连接
常规步骤
- 定义TLM传输的数据类型
- 在各个层次的component声明并创建端口对象
- connect()完成端口连接
- imp中需要提供给initiator的可调用方法,必须!否则端口连接了也无法进行数据传输
实例
class request extends uvm_transaction;
byte cmd;
int addr;
int req;
endclass
class response extends uvm_transaction;
byte cmd;
int addr;
int rsp;
int status;
endclass
class comp1 extends uvm_agent;
uvm_blocking_get_port #(request) bg_port;//port被数据流指向为get
`uvm_component_utils(comp1)
...
endclass
class comp2 extends uvm_agent;
uvm_blocking_get_port #(request) bg_port;
uvm_nonblocking_put_imp #(request, comp2) nbp_imp;//imp被数据流指向为put
`uvm_component_utils(comp2)
...
function bit try_put (request req);
function bit can_put();
endclass
class comp3 extends uvm_agent;
uvm_blocking_transport_port #(request, response) bt_port;//双向端口transport
`uvm_component_utils(comp3)
...
endclass
class comp4 extends uvm_agent;
uvm_blocking_get_imp #(request, comp4) bg_imp;//发送数据流的imp是get
uvm_nonblocking_put_port #(request) nbp_port;//发送数据流的port是put
`uvm_component_utils(comp3)
...
task get(output request req);
endclass
class comp5 extends uvm_agent;
uvm_blocking_transport_imp #(request, response, comp5) bt_imp;//双向imp
`uvm_component_utils(comp5)
...
task transport(request req, output response rsp);
endclass
class agent1 extends uvm_agent;
uvm_blocking_get_port #(request) bg_port;//从上往下依次对应3个端口
uvm_nonblocking_put_export #(request) nbp_exp;
uvm_blocking_transport_port #(request, response) bt_port;
comp1 c1;
comp2 c2;
comp3 c3;
`uvm_compontne_u