【UVM】TLM通信机制

基本概念

        TLM(transaction level modeling)是一个基于事务(transaction)的通信方式,每次传输一个transaction,一个transaction就是把具有某一特定功能的一组信息封装在一起而成为的一个类。

通信对象

  • 发起者:数据的请求方,也就是initiator
  • 响应者:数据的响应方,也就是target
  • 注:发起者和响应者不代表数据的流向性。initiator:永远有主动权,不论时请求数据还是主动发送数据,永远是发起的那一方;target:永远时被动的,只能被动的接收数据,或者被通知需要发送数据; 

传输方式

put操作

        单向传输,通信动作发起者A把一个transaction发送给B,数据流从A流向B

get操作

        单向传输,通信动作发起者A向B索取一个transaction,数据流从B流向A

transport操作

        双向传输,又称做request-response操。相当于一次put操作加一次get操作,这两次操作的“发起者”都是A,目标都是B,数据从A流到B,再从B流向A。

通信端口

端口定义

  • port端口:initiator的端口,有阻塞赋值和非阻塞赋值的区分
  • export端口:initiator和target的中转端口,有阻塞赋值和非阻塞赋值的区分
  • imp端口:target端口,有阻塞赋值和非阻塞赋值的区分
  • 注意:
    • 端口优先级:port > export > imp
    • 在connect_phase中使用connect()建立连接关系时,只有优先级高的才能调用connect()做连接(即port可以连接port、export或者imp;export可以连接export或者imp;imp只能作为数据传送的重点,无法扩展连接)
    • 在UVM中,只有IMP才能作为连接关系的终点

UVM常见端口

PORT端口
//blocking阻塞;nonblocking非阻塞;不含这两者表示既可以阻塞也可以非阻塞
uvm_blocking_put_port#(T);
uvm_nonblocking_put_port#(T);
uvm_put_port#(T);
uvm_blocking_get_port#(T);
uvm_nonblocking_get_port#(T);
uvm_get_port#(T);
uvm_blocking_peek_port#(T);
uvm_nonblocking_peek_port#(T);
uvm_peek_port#(T);
uvm_blocking_get_peek_port#(T);
uvm_nonblocking_get_peek_port#(T);
uvm_get_peek_port#(T);
uvm_blocking_transport_port#(REQ, RSP);
uvm_nonblocking_transport_port#(REQ, RSP);
uvm_transport_port#(REQ, RSP);
EXPORT端口
uvm_blocking_put_export#(T);
uvm_nonblocking_put_export#(T);
uvm_put_export#(T);
uvm_blocking_get_export#(T);
uvm_nonblocking_get_export#(T);
uvm_get_export#(T);
uvm_blocking_peek_export#(T);
uvm_nonblocking_peek_export#(T);
uvm_peek_export#(T);
uvm_blocking_get_peek_export#(T);
uvm_nonblocking_get_peek_export#(T);
uvm_get_peek_export#(T);
uvm_blocking_transport_export#(REQ, RSP);
uvm_nonblocking_transport_export#(REQ, RSP);
uvm_transport_export#(REQ, RSP);
IMP端口 
//IMP定义中的blocking、nonblocking、put、get、peek、get_peek、transport等关键字的意思并不是它们发起做相应类型的操作,而只意味着它们可以和相应类型的PORT或者EXPORT进行通信
//每一个IMP需要和一个component相对应
uvm_blocking_put_imp#(T, IMP);
uvm_nonblocking_put_imp#(T, IMP);
uvm_put_imp#(T, IMP);
uvm_blocking_get_imp#(T, IMP);
uvm_nonblocking_get_imp#(T, IMP);
uvm_get_imp#(T, IMP);
uvm_blocking_peek_imp#(T, IMP);
uvm_nonblocking_peek_imp#(T, IMP);
uvm_peek_imp#(T, IMP);
uvm_blocking_get_peek_imp#(T, IMP);
uvm_nonblocking_get_peek_imp#(T, IMP);
uvm_get_peek_imp#(T, IMP);
uvm_blocking_transport_imp#(REQ, RSP, IMP);
uvm_nonblocking_transport_imp#(REQ, RSP, IMP);
uvm_transport_imp#(REQ, RSP, IMP);

通信方式

一对一通信(port-export-imp)

基本概念

类型

  • port-imp互联
  • export-imp互联
  • port-port互联,PORT与PORT之间的连接可以有无限多层。
  • export-export互联,EXPORT与EXPORT之间的连接可以有无限多层

端口互联对应关系

发起者(port/export/transport)类型imp中对应的任务/函数
blocking_putput
nonblocking_puttry_put和can_put
putput、try_put和can_put
blocking_getget
nonblocking_gettry_get和can_get
getget、try_get和can_get
blocking_peekpeek
nonblocking_peektry_peek和can_peek
peekpeek、try_peek和can_peek
blocking_get_peekget和peek
nonblocking_get_peektry_get和can_get、try_peek和can_peek
get_peekget和peek、try_get和can_get、try_peek和can_peek
blocking_transporttransport
nonblocking_transportnb_transport
transporttransport和nb_transport

 注:对于blocking的端口,可以定义相应的任务或函数;对于nonblocking端口,只能定义函数

一对多通信(analysis_port/analysis_export-analysis_imp)

基本概念

  • 一个analysis_port(analysis_export)可以连接多个analysis_imp
  • 对于analysis_port和analysis_export来说,没有阻塞和非阻塞的概念
  • analysis_port如果和analysis_export直接相连也会出错,只有在analysis_export后面再连接一级uvm_analysis_imp,才不会出错

端口互联对应关系

analysis_port和analysis_export类型analysis_imp对应函数
*write

注:对于同一个component下需要用到多个uvm_analysis_imp的场景,解决方式可通过定义宏`uvm_analysis_imp_decl(_xxx),声明多个后缀不一样的imp,UVM会根据后缀内建不同的imp。

//my_scoreboard.sv
 
`uvm_analysis_imp_decl(_monitor)
`uvm_analysis_imp_decl(_model)
class my_scoreboard extends uvm_scoreboard;
    my_transaction expect_queue[$];
    uvm_analysis_imp_monitor#(my_transaction, my_scoreboard) monitor_imp;
    uvm_analysis_imp_model#(my_transaction, my_scoreboard) model_imp;
    ...
 
    extern function void write_monitor(my_transaction tr);
    extern function void write_model(my_transaction tr);
    extern virtual task main_phase(uvm_phase phase);
 
endclass
function void my_scoreboard::write_model(my_transaction tr);
    expect_queue.push_back(tr);
endfunction
function void my_scoreboard::write_monitor(my_transaction tr);
    my_transaction tmp_tran;
    bit result;
    if(expect_queue.size() > 0) begin
        ...
    end
endfunction

FIFO通信

基本概念

  • uvm_analysis_fifo,本质是一块缓存加两个imp

类型

端口类型区别

uvm_tlm_fifo

无以下
uvm_tlm_analysis_fifo

有一个analysis_export端口,及其配套的write函数

FIFO端口

  • FIFO中端口有关键字export,但是其类型却是IMP。如analysis_export的原型如下:
    uvm_analysis_imp #(T, uvm_tlm_analysis_fifo #(T)) analysis_export;
  • FIFO中的get端口,get任务被调用时,FIFO内部缓存中会少一个transaction
  • FIFO中的peek端口,peek任务被调用时,FIFO会把transaction复制一份发送出去,其内部缓存中的transaction数量并不会减少
  • 当FIFO中的put端口被连接时,FIFO内部被定义的put任务被调用,它把传递过来的transaction放在FIFO内部的缓存里,同时,把这个transaction通过put_ap使用write函数发送出去
    virtual task put( input T t );
        m.put( t );
        put_ap.write( t );
    endtask
  • 与put_ap相似,当FIFO的get任务被调用时,同样会有一个transaction从get_ap上发出
    virtual task get( output T t );
        m_pending_blocked_gets++;
        m.get( t );
        m_pending_blocked_gets--;
        get_ap.write( t );
    endtask

 FIFO调试函数

函数作用
used查询FIFO缓存中有多少transaction
is_empty判断当前FIFO缓存是否为空
is_full判断当前FIFO缓存是否为满
flush清空FIFO缓存中的所有数据,它一般用于复位等操作
//FIFO的new函数原型
function new(string name, uvm_component parent = null, int size = 1);
//第三个参数size,用于设定FIFO缓存的上限,默认的情况下为1。若要把缓存设置为无限大小,将传入的size参数设置为0即可。通过size函数可以返回这个上限值。

FIFO与IMP对比

  • FIFO对于初学者,使用方式比IMP简洁易上手

  • FIFO连接的方式增加了env中代码的复杂度

  • 对于使用端口数组的情况,FIFO要优于IMP

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值