电子说
在简单的测试平台里,component之间通过变量或者config_db机制通信是可行的,但是如果在复杂测试平台中依然使用这种耦合性很强的方式通信的话,就不太行了。
因此,UVM提供了TLM这样的概念。接下来将会从需求出发,逐步引入port、export、imp、analysis端口、uvm_analysis_imp_decl宏以及FIFO等。
说明:这里以monitor和scoreboard之间的通信为例
现有机制更多通信问题
说明:以blocking_put系列端口,PORT>EXPORT>IMP的连接举例说明
注意:EXPORT可以省略,即 PORT直接连接到IMP
A|analysis_port发起端口操作write :task A::main_phase中A_ap.write(tr);
建立A|analysis_port和(B或C)|analysis_imp,的连接 :A(B或C)的顶层模块my_env::connect_phase中
A_inst.A_ap.connect(B_inst.B_imp);
A_inst.A_ap.connect(C_inst.C_imp);
建立(B或C)|analysis_imp和(B或C)中操作write的连接 :(B或C)模块定义中:
uvm_analysis_imp#(my_transaction, B) B_imp;或
uvm_analysis_imp#(my_transaction, C) C_imp;
(B或C)中操作write的实现 :
function void B::write
function void C::write
一个component(my_scoreboard)内有多个IMP时,依据前面知识,component(my_scoreboard)中只能有一个write方法,这如何处理两个imp(来自输出监视monitor 和 来自参考模型model)
通过宏uvm_analysis_imp_decl,在component(my_scoreboard)中添加不同的后缀以区分两个imp的处理逻辑。具体实现如下:
通过宏uvm_analysis_imp_decl声明两个后缀_monitor和_model
uvm_analysis_imp_decl(**_monitor**)
uvm_analysis_imp_decl( _model )
使用带后缀的analysis_imp端口类声明两个analysis_imp端口
uvm_analysis_imp**_monitor**#(my_transaction, my_scoreboard) monitor_imp;
uvm_analysis_imp**_model**#(my_transaction, my_scoreboard) model_imp;
使用带后缀的write方法实现analysis_imp对信号的处理逻辑
extern function void write**_monitor**(my_transaction tr);
extern function void write**_model**(my_transaction tr);
宏uvm_analysis_imp_decl的特性会让 相同后缀的 analysis_imp端口 和 write函数 对应上
function void my_scoreboard ::write_model(my_transaction tr);
function void my_scoreboard ::write_monitor(my_transaction tr);
将imp的实现逻辑放在FIFO中,而component(my_scoreboard)作为PORT端,主动请求get到FIFO中的数据,关键代码如下:
// my_scoreboard类中
uvm_blocking_get_port #(my_transaction) exp_port;
uvm_blocking_get_port #(my_transaction) act_port;
// task my_scoreboard::main_phase中
exp_port.get(get_expect); // 获取的数据存到get_expect中
act_port.get(get_actual); // 获取的数据存到get_actual中
// my_env类中
uvm_tlm_analysis_fifo #(my_transaction) agt_scb_fifo;
uvm_tlm_analysis_fifo #(my_transaction) agt_mdl_fifo;
uvm_tlm_analysis_fifo #(my_transaction) mdl_scb_fifo;
// function void my_env::connect_phase中
i_agt.ap.connect(agt_mdl_fifo.analysis_export);
mdl.port.connect(agt_mdl_fifo.blocking_get_export);
mdl.ap.connect(mdl_scb_fifo.analysis_export);
scb.exp_port.connect(mdl_scb_fifo.blocking_get_export);
o_agt.ap.connect(agt_scb_fifo.analysis_export);
scb.act_port.connect(agt_scb_fifo.blocking_get_export);
注意:FIFO中的analysis_export和blocking_get_export虽然名字中有关键字export, 但是其类型却是IMP
个人推荐使用FIFO,尤其是对于使用端口数组的情况。因为ap与imp直接相连不能使用for循环(write函数需要一个一个写,没法用数组),会导致代码量增加,理解困难。
全部0条评论
快来发表一下你的评论吧 !