标签:互联 PORT connect EXPORT UVM phase port TLM uvm
UVM TLM通信之端口的互联
PORT与EXPORT的连接
如图所示,ABCD四个端口, 要在A和B之间、C和D之间通信。为了实现这个目标,必须要在A和B之间、C和D之间建立一种连接关系,否则的话,A如何知道是和B通信而不是和C或者D通信呢?所以一定要在通信前建立连接关系。
如A要和B通信(A是发起者),那么可以这么写:A.port.connect(B.export),但是不能写成B.export.connect(A.port)。因为在通信的过程中,A是发起者,B是被动承担者。这种通信时的主次顺序也适用于连接时,只有发起者才能调用connect函数,而被动承担者则作为connect的参数。
使用上述方式建立A.PORT和B.EXPORT之间的连接关系。A的代码为:
class A extends uvm_component;
`uvm_component_utils(A)
uvm_blocking_put_port#(my_transaction) A_port;
...
endclass
function void A::build_phase(uvm_phase phase);
super.build_phase(phase);
A_port = new("A_port", this);
endfunction
task A::main_phase(uvm_phase phase);
endtask
其中A_port在实例化的时候第一个参数是名字,而第二个参数则是一个uvm_component类型的父结点变量
。
B的代码类同A,在env中建立两者之间关系的连接如下:
class my_env extends uvm_env;
A A_inst;
B B_inst;
...
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
A_inst = A::type_id::create("A_inst", this);
B_inst = B::type_id::create("B_inst", this);
endfunction
endclass
function void my_env::connect_phase(uvm_phase phase);
super.connect_phase(phase);
A_inst.A_port.connect(B_inst.B_export);
endfunction
注:PORT和EXPORT恰如一道门,它们只是一个通行的作用,它不可能把一笔transaction存储下来,没有存储作用,除了转发操作之外不作其他操作。因此,这笔transaction一定要由B_export后续的某个组件进行处理。在UVM中,完成这种后续处理的也是一种端口:IMP。
PORT和IMPORT的连接
有了IMP之后,之前的PORT与EXPORT之间的连接就可以实现了。下图为component在连接中的作用
A和B的代码为:
class A extends uvm_component;
`uvm_component_utils(A)
uvm_blocking_put_port#(my_transaction) A_port;
...
endclass
...
task A::main_phase(uvm_phase phase);
my_transaction tr;
repeat(10) begin
#10;
tr = new("tr");
assert(tr.randomize());
A_port.put(tr);
end
endtask
//------------------------------------------------------------------------------------------
class B extends uvm_component;
`uvm_component_utils(B)
uvm_blocking_put_export#(my_transaction) B_export;
uvm_blocking_put_imp#(my_transaction, B) B_imp;
...
endclass
function void B::connect_phase(uvm_phase phase);
super.connect_phase(phase);
B_export.connect(B_imp);
endfunction
function void B::put(my_transaction tr);
`uvm_info("B", "receive a transaction", UVM_LOW)
tr.print();
endfunction
在B的代码中,关键是要实现一个put函数/任务。如果不实现,将会给出错误提示
在UVM中,只有IMP才能作为连接关系的终点。如果是PORT或者EXPORT作为终点,则会报错。
A_port的put操作最终要落到B的put上。所以在B中要定义一个名字为put的任务/函数。
当B中完成B_imp和put的定义后,在env的connect_phase就需要把Aport和B_imp连接在一起了:
function void my_env::connect_phase(uvm_phase phase);
super.connect_phase(phase);
A_inst.A_port.connect(B_inst.B_imp);
endfunction
EXPORT和IMP的连接
PORT可以与IMP相连接,同样的EXPORT也可以与IMP相连接,其连接方法与PORT和IMP的连接完全一样。之前完成了EXPORT与IMP的连接,不过在那个连接中EXPORT只是作为中间环节,这里把EXPORT作为连接的起点。
除了A_port变成B_export之外,其他没有任何改变。在B中也必须定义一个名字为put的任务。
PORT和PORT的连接
在之前的连接中,都是不同类型的端口之间连接(PORT与IMP、PORT与EXPORT、EXPORT与IMP),且不存在层次的关系。在UVM中,支持带层次的连接关系,
在上图中,A与C中是PORT,B中是IMP。UVM支持C的PORT连接到A的PORT,并最终连接到B的IMP。
C和A的代码如下:
class C extends uvm_component;
`uvm_component_utils(C)
uvm_blocking_put_port#(my_transaction) C_port;
...
endclass
task C::main_phase(uvm_phase phase);
my_transaction tr;
repeat(10) begin
#10;
tr = new("tr");
assert(tr.randomize());
C_port.put(tr);
end
endtask
//-------------------------------------------------------------------------------------------
class A extends uvm_component;
`uvm_component_utils(A)
C C_inst;
uvm_blocking_put_port#(my_transaction) A_port;
...
endclass
function void A::build_phase(uvm_phase phase);
super.build_phase(phase);
A_port = new("A_port", this);
C_inst = C::type_id::create("C_inst", this);
endfunction
function void A::connect_phase(uvm_phase phase);
super.connect_phase(phase);
C_inst.C_port.connect(this.A_port);
endfunction
task A::main_phase(uvm_phase phase);
endtask
其他代码仅需修改端口类型,其他均相同;
PORT与PORT之间的连接不只局限于两层,可以有无限多层。
EXPORT和EXPORT的连接
在下图中,A中是PORT,B与C中是EXPORT,B中还有一个IMP。UVM支持C的EXPORT连接到B的EXPORT,并最终连接到B的IMP。
A、B代码同前,C的代码和env代码如下:
class C extends uvm_component;
`uvm_component_utils(C)
B B_inst;
uvm_blocking_put_export#(my_transaction) C_export;
...
endclass
function void C::build_phase(uvm_phase phase);
super.build_phase(phase);
C_export = new("C_export", this);
B_inst = B::type_id::create("B_inst", this);
endfunction
function void C::connect_phase(uvm_phase phase);
super.connect_phase(phase);
this.C_export.connect(B_inst.B_export);
endfunction
task C::main_phase(uvm_phase phase);
endtask
//-------------------------------------------------------------------------------------------
function void my_env::connect_phase(uvm_phase phase);
super.connect_phase(phase);
A_inst.A_port.connect(C_inst.C_export);
endfunction
同样的,EXPORT与EXPORT之间的连接也不只局限于两层,也可以有无限多层。
这篇笔记参考《UVM实战》、《芯片验证漫游指南》和某验证视频整理而成,仅作学习心得交流,如果涉及侵权烦请请告知,我将第一时间处理。
标签:互联,PORT,connect,EXPORT,UVM,phase,port,TLM,uvm 来源: https://blog.csdn.net/qq_40051553/article/details/121352632
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。