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中并重复两次。