TLM blocking put port

1.创建一个packet类,包含两个数据,用于在不同component中传递

class Packet extends uvm_object;

    //两种bit型的随机变量
    rand bit [7:0] addr;
    rand bit [7:0] data;

    // 使用宏注册,和字段宏便于后续打印
    `uvm_object_utils_begin(Packet)
        `uvm_field_int(addr,UVM_ALL_ON)
		`uvm_field_int(data,UVM_ALL_ON)
	`uvm_object_utils_end

    function new (string name = "Packet");
        super.new(name);
    endfunction
endclass

2.定义一个component类A,在A中完成对数据发送端口的建立并发送数据(注意端口的类型为阻塞型 blocking)

class A extends uvm_component;
    //使用宏注册
    `uvm_component_utils(A)

    //使用uvm_blocking_put_port创建一个参数化的类 实现发送端口的建立
    uvm_blocking_put_port #(Packet) m_put_port;

    //重复次数
    int m_num_tx;

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

    //在build中实现对参数化类的实例化
    virtual function void build_phase (uvm_phase phase);
        super.build_phase (phase);
        m_put_port = new("m_put_port",this);
    endfunction

    //在 run_phase 中实现对数据的发送
    virtual task run_phase (uvm_phase phase);
        phase.raise_objection(this);
        repeat (m_num_tx) begin
        
            //对packet实例化,并随机化packet中的两个变量
            Packet pkt = Packet :: type_id :: create ("pkt");
            assert(pkt.randomize());

            `uvm_info ("A","Packet sent to B",UVM_LOW);
            
            //使用字段宏的print函数打印packet中的变量值
            pkt.print(uvm_default_line_printer);

            //在发送端口使用 put函数或者任务(在接受端定义) 发送pkt中的数据给接收端
            m_put_port.put(pkt);
        end
        phase.drop_objection(this);
    endtask
endclass

3.定义一个componB,在B中完成对数据接收端口的建立,并创建 put任务或者函数用于发送端发送数据。

class B extends uvm_component;
    `uvm_component_utils (B)

   //接收端口的建立
    uvm_blocking_put_imp #(Packet,B) m_put_imp;

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

    //接收端口的实例化
    function void build_phase (uvm_phase phase);
        super.build_phase (phase);
        m_put_imp = new("m_put_imp",this);
    endfunction

   //在接收端定义一个 put 任务(对于 blocking 端口名称应定义为put,且可以是函数或者任务)
    virtual task put (Packet pkt);
        `uvm_info ("B","Packet received from A",UVM_LOW);
        pkt.print(uvm_default_line_printer);
    endtask
endclass

4.定义更高层次的test类,实现发送端与接收端的连接

//在更高一层的component节点中实现发送端与接收端的连接
class test extends uvm_test;

    //使用宏注册
    `uvm_component_utils (test)

    //A和B创建对象
    A comA;
    B comB;

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

    //实例化A和B
    function void build_phase (uvm_phase phase);
        super.build_phase (phase);
        comA = A ::type_id :: create ("comA",this);
        comB = B ::type_id :: create ("comB",this);
        comA.m_num_tx = 2;
    endfunction

    //在connect中实现发送端口与接收端口的连接
    virtual function void connect_phase (uvm_phase phase);
        comA.m_put_port.connect (comB.m_put_imp);
    endfunction
endclass
		

//在顶层模块 run_test
module top_tb;

	initial begin

		run_test("test");

	end

endmodule

5.sim log

实现了从A中把packet的数据发送到B中并重复两次。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值