TLM通信

一、TLM基础

  • 1.为何引入TLM通信

  • 2.通信对象如何分类

  • 3.端口类型

  • 4.TLM的通信步骤

二、单向通信

  • 1.单向通信示例

  • class itrans extends uvm_transaction;
        int id;
        int data;
        ...
    endclass
    
    class otrans extends uvm_transaction;
        int id;
        int data;
        ...
    endclass
    
    class comp1 extends uvm_component;
        uvm_blokcing_put_port #(itrans) bp_port;
        uvm_nonblokcing_get_port #(otrans) nbg_port;
        `uvm_component_utils(comp1)
        ...
    
        task run_phase(uvm_phase phase);
            itrans itr;
            otrans otr;
            
            int trans_num = 2;
            fork
            begin
                for(int i = 0; i < trans_num; i++)begin 
                    itr = new("itr", this);
                    itr.id = i;
                    itr.data = 'h10 + i;
                    this.bp_port put(itr);
                    `uvm_info("PUT", $sformatf("put itrans id: 'h0x, data: 'h%0x", itr.id, itr.data), UVM_LOW)
                end
            end
        
            begin
                for(int j = 0; j < trans_num; j++)begin
                forever begin
                    if(this.nbg_port.try_get(otr) == 1)break;
                    else #1ns;
                    end
                `uvm_info("TRYGET", $sformatf("get otrans id: 'h%0x, data: 'h%0x", otr_id, otr_data), UVM_LOW)
                end
            end
            join
        endtask
    endclass
    
    class comp2 extends uvm_component;
        uvm_blocking_put_imp #(trans; comp2) bp_imp;
        uvm_nonblocking_get_imp #(otrans, comp2) nbg_imp;
        itran itr_q[$];
        `uvm_component_utils(comp2)
        ...
    
        task put(trans t);
            itr_q.push_back(t);
        endtask
    
        function bit try_get(output otrans t);
            itrans i;
            if(itr_q.size() != 0)begin
                i = itr_q.pop_front();
                t = new("t", this);
                t.id = i.id;
                t.data = i.data << 0;
                return i;
            end
            else return 0;
        endfunction
    
        function bit can_get();
            if(itr_q.size() != 0)return i;
            else return 0;
        endfunction
    endclass
    
    class env1 extends uvm_env;
        comp1 c1;
        comp2 c2;
        `uvm_component_utils(env1)
        ...
        
        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
            c1 = comp1::type_id::creat("c1", this);
            c2 = comp2::type_id::creat("c2", this);
        endfunction
    
        function void connect_phase(uvm_phase phase);
            super.connect_phase(phase);
            c1.bp_port.connect(c2.bp_imp);
            c1.nbg_port.connect(c2.nbp_imp);
        endfunction
    endclass

三、双向通信

1.双向通信示例

class comp1 extends uvm_component;
    uvm_blocking_transaport_port #(itrans, otrans) bt_port;
    `uvm_component_utils(comp1);
    ...

    task run_phase(uvm_phase phase);
        itrans itr;
        otrans otr;
        int trans_num = 2;
        for(int i = 0; i < trans_num; i++)begin
            itr = new("itr", this);
            itr.id = 1;
            itr.data = 'h10 + i;
            this.bt_port.transport(itr, otr);
            `uvm_info("TRSPT", $sformatf("put itrans id: 'h%0x, data: 'h%0x | got otrans id: 'h%0x, data: 'h%0x", itr.id, itr.data, otr.id, otr.data), UVM_LOW)
        end
    endtask
endclass


class comp2 extends uvm_component;
    uvm_blocking_transport_imp #(itrans, otrans, comp2) bt_imp;
    `uvm_component_utils(comp2)
    ...

    task transport(itrans req, output otrans rsp);
        rsp = new("rsp", this);
        rsp.id - req.id;
        rsp.data = req.data << 0;
    endtask
endclass


class env1 extends uvm_env;
    comp1 c1;
    COMP2 C2;
    `uvm_component_utils(env1)
    ...
    
    function void build_phase(uvm_phase phase);
        super.build_phase([phase);
        c1 = comp1::type_id::create("c1", tthis);
        c2 = comp2::type_id::create("c2",  this);
    endfunction

    function void connect_phase(uvm_phase);
        super.connect_phase(phase);
        c1.bt_port.connect(c2.bt imp);
    endfunction
endclass

四、多向通信

1.多向通信示例

`uvm_blocking_put_imp_decl(_p1)
`uvm_blocking_put_imp_decl(_p2)

class comp1 extends uvm_component;
    uvm_blocking_put_port #(itrans)bp_port1;
    uvm_blocking_put_port #(itrans)bp_port2;
    `uvm_component_utils(comp1)
    ...
    
    task run_phase(uvm_phase phase);
        itrans itr1, itr2;
        int trans_num = 2;
        fork
            for(int i = 0; i < trans_num; i++)begin
                itr1 = new("itr1", this);
                itr1.id = i;
                itr1.data = 'h10 + i;
                this.bp_port1.put(itr1);
            end

            for(int i = 0; i <trans_num; i++)begin
                itr2 =new("itr2", this);
                itr2.id = 'h10 + i;
                itr2.data = 'h20 + i;
                this.bp_port.put(itr2);
            end
        join
    endtask
endclass


class comp2 extends uvm_component;
    uvm_blocking_put_imp_p1 #(trans, comp2)bt_imp_p1;
    uvm_blocking_put_imp_p2 #(trans, comp2)bt_imp_p2;
    itrans itr_q[$];
    semaphore key;
    `uvm_component_utils(comp2)
    ...

    task put_p1(itrans t);
        key.get();
        itr_q.push_back();
        `uvm_info("PUT P1", $sformatf("put itrans id: 'h%0x, data:'h%0x", t.id, t.data), UVM_LOW)
        key_put();
    endtask
endclass

class env1 extends uvm_env;
    comp1 c1;
    cimp2 c2;
    `uvm_cimponent_utils(env1)
    ...
    
    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        c1 = comp1::type_id::create("c1, this");
        c2 = comp2::type_id::create("c2, this");
    endfunction

    function void connect_phase(uvm_phase phase);
        super.connect_phase(phase);
        c1.bp_port.connect(c2.bt_imp_p1);
        c1.bp_port.connect(c2.bt_imp_p2);
    endfunction 
endclass

五、通信管道

1.uvm_tlm_fifo创建

uvm_tlm_fifo #(T) tlm_fifo; //data type is T
tlm_fifo = new("tlm_fifo", this, 2); //create a fifo with depth 2

//denifined new()
function neww(string name, uvm_component parent = null, int size  = 1
)

2.tlm fifo示例

class env extendds uvm_env;
    `uvm_component_utils(env)
    comp1 c1;
    comp2 c2;

    // create the tlm fifo can accept trans
    uvm_tlm_fifo #(trans) tlm_fifo; //defined tlm fifo

    function new(string name = "env", uvm_component parent = null);
        super.new(name, parent);
    endfunction

    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        c1 = comp1::type_id::create("c1", this);
        c2 = comp2::type_id::create("c2", this);
        
        tlm_fifo = new("tlm_fifo", this, 2);
    endfunction

    virtual task run_phase(uvm_phase phase);
        forever begin
            #10ns;
            if(tlm_fifo.is_full())//see uvm databook
            `uvm_info("fifo is full", UVM_LOW)
        end
    endtask
endclass

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值