UVM中的TLM(事务级建模)通信(1)

1.验证平台内部的通信

        我们希望在验证平台内部找到两个component之间适合通信的方法,在接触TLM之前,想到的方法无非有采用全局变量、通过config_db传输等等。然而全局变量因为安全性不高,是我们长期以来竭力避免使用的方法;config_db虽然相对安全,但需要拉入basetest的参与,也不能保证由basetest派生而来的类会不会改变config_db类中某些变量的值,仍然存在风险。

        不仅如此,加入了非阻塞和阻塞的概念之后,上述方法都难以满足要求。如果scoreboard主动向monitor请求数据,该如何实现这样的功能呢?

        答案是在monitor和scoreboard之间建立一个专门的通道,借由TLM我们可以实现这种功能。

2.TLM(transaction level modeling)

        TLM起源于SystemC一种通信标准,所谓的transcation level是相对DUT中各个模块之间信号线级别的通信而言。transaction就是把具有某一特定功能的一组信息封装在一起成为的一个类。

        注意:TLM仅仅适用于component之间的连接。

2.1 initiator与target

        initiator与target的概念描述的是控制流的方向,其中initiator永远是数据的请求方而target是响应方,这与数据究竟从谁流向谁无关。也就是说initiator永远有主动权,不论请求数据还是主动发送数据,永远是发起的那一方。

        常用的操作包含有put、get、transport等。

        put描述的是数据从initiator流向target;

        get描述的是数据从target流向initiator;

        transport相当于一次put加上一次get。三种操作都有阻塞和非阻塞之分。

2.2 各种端口的互联

        通信端口分为3类:port、export、imp,表示从initiator向target发起的request传输方向。

        port:通信请求方initiator的发起端;

        export:作为initiator和target中间层次的端口;

        imp:只能作为target接收请求的响应端,它无法作为中间层次的端口,imp为通信终点。

        每种端口的声明各有15种,对应是否阻塞以及具体使用的通信方法:

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);

        以port为例,这里声明的是采用put方法的port端口,T标志的是transaction的类型。对export的声明,只需要把port改成export,其他均与port一致。

        而imp的声明还需要加入一个参数:IMP指示当前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, 使用connect()建立连接关系时,只有优先级高的才能调用connect()做连接,即port可以连接port、export或者imp;export可以连接export或者imp;imp只能作为数据传送的终点,无法扩展连接,无法调用connect()。

        下面让我们来连接一个简单的get型传输:

class A extends uvm_component;         //A作为动作接收者
    `uvm_component_utils(A)

uvm_blocking_get_export#(my_transaction) A_export;
uvm_blocking_get_imp#(my_transaction,A) A_imp;
my_transaction tr_q[$];
......    // extern A的一系列phase

endclass

function void A::build_phase(uvm_phase phase);
    super.build_phase(phase);
    A_export = new("A_export",this);
    A_imp = new("A_imp",this);
endfunction

function void A::connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    A_export.connect(A_imp);
endfunction

task A::get(output my_transaction tr);  // A作为接收者需要定义get任务
    while(tr_q.size()==0) #2;
    tr = tr_q.pop_front();
endtask

task A::main_phase(uvm_phase phase);  
    my_transaction tr;
    repeat(10) begin
        #10;
        tr = new("tr");
        tr_q.push_back(tr);
    end
endtask

A的get任务每隔两个时间单位检查队列中是否有数据,如果有则向外发出,当B在main_phase中调用get任务时,最终执行的是A的get任务。A的connect phase需要完成export与imp的连接。

class B extends uvm_component;
    `uvm_component_utils(B);

    `uvm_blocking_get_port#(my_transaction) B_port;
......
endclass

function void B::build_phase(uvm_phase phase);
    super.build_phase(phase);
    B_port = new("B_port",this);
endfunction

task B::main_phase(uvm_phase phase);
    my_transaction tr;
    while(1)  begin
        B_port.get(tr);
        `uvm_info("B","get a transaction",UVM_LOW);
        tr.print();
    end
endtask

在env中对他们进行连接:

function void my_env::connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    B_inst.B_port.connect(A_inst.A_export);
endfunction

以上介绍了blocking_get_port与blocking_get_export、blocking_get_imp的连接。需要谨记的是连接的终点一定是一个imp。若我们需要使用到nonblocking端口,则要将原先的task换用函数(不耗时)来实现。

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值