UVM 通信方式

UVM 通信方式,第1张

UVM 通信方式 1、UVM中的analysis 端口

包含有analysis_port和analysis_export两种端口,它们与port、export和imp的主要区别在于:

第一,默认情况下,analysis_port(analysis_export)可以连接多个IMP,而put和get系列端口连接一个IMP(除非在例化时修改连接数量)。

第二,analysis_port和analysis_export没有阻塞与非阻塞之分,而put和get系列端口有阻塞与非阻塞之分。

第三,put系列端口有put、try_put和can_put等 *** 作;get系列端口有get、try_get和can_get等 *** 作;analysis_port和analysis_export端口只有一种 *** 作:write。在analysis_imp所在的component,必须定义一个名字为write的函数。

2、analysis 端口连接关系

A的代码:

class A extends uvm_component;
        `uvm_component_utils(A);
        uvm_analysis_port#(my_transaction) A_ap;//定义端口类型
endclass
function void A::build_phase(uvm_phase phase);
        super.build_phase(phase);
        A_ap = new("A_port",this);//例化端口
endfunction
task A::main_phase(uvm_phase phase);
        my_transaction tr;
        tr = new("tr");
        assert(tr.randomize());
        A_ap.write(tr);//发送tr数据包
endtask

B的代码:

class B extends uvm_component;
		`uvm_component_utils(B);
		uvm_analysis_imp#(my_transaction,B) B_imp;//定义端口类型
endclass
function void B::build_phase(uvm_phase phase);
		super.build_phase(phase);
		B_imp = new("B_imp",this);		
endfunction
function void B::write(my_transaction tr);
		tr.print();
endfunction

在env中建立起两者的连接:

class my_env extends uvm_env;
		A A_inst;
		B B_inst;
endclass
function void my_env::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
function void my_env::connect_phase(uvm_phase phase);
		super.connect_phase(phase);
		A_inst.A_ap.connect(B_inst.B_imp);
endfunction
3、特别说明

与put系列端口的PORT和EXPORT直接相连出错一样,analysis_port与analysis_export直接相连也会出错,只有在analysis_export后面连接一级analysis_imp才不会出错。

4、uvm_analysis_imp_decl宏的使用

当出现analysis_imp所在的component需要接收多路数据的情况时,但write只有一个,那么该如何定义write函数呢?这时就用到了宏uvm_analysis_imp_decl。例子如下:

`uvm_analysis_imp_decl(_monitor)
`uvm_analysis_imp_decl(_model)
class my_scoreboard extends uvm_scoreboard;
		my_transaction tr;
		
		uvm_analysis_imp_monitor#(my_transaction ,my_scoreboard) monitor_imp;
		uvm_analysis_imp_model#(my_transaction ,my_scoreboard) model_imp;
		
		extern function void write_monitor(my_transaction tr);
		extern function void write_model(my_transaction tr);
endclass
function void my_scoreboard::write_monitor(my_transaction tr);

endfunction
function void my_scoreboard::write_model(my_transaction tr);

endfunction

只要完成后缀的声明,并在write后面加上相应的后缀即可正常工作。

5、使用fifo通信

fifo的本质是一个缓存加两个IMP,例子如下:

class my_scoreboard extends uvm_scoreboard;
		my_transaction tr;
		my_transaction get_exp;
		my_transaction get_act;
		
		uvm_blocking_get_port#(my_transaction) exp_port;
		uvm_blocking_get_port#(my_transaction) act_port;
endclass

task my_scoreboard::main_phase(phase);
		fork
			while(1)begin
				exp_port.get(get_exp);//获取数据包
			end
			while(1)begin
				act_port.get(get_act);//获取数据包
			end			
		join
endtask

在env中建立起连接:

```typescript
class my_env extends uvm_env;
		my_agent i_agt;
		my_agent o_agt;
		my_scoreboard scb;
		my_model mdl;

		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;
endclass

function void my_env::connect_phase(uvm_phase phase);
		super.connect_phase(phase);
		i_agt.A_ap.connect(agt_mdl_fifo.analysis_export);//input monitor->fifo
		mdl.port.connect(agt_mdl_fifo.blocking_get_export);//fifo->model
		mdl.ap.connect(mdl_scb_fifo.analysis_export);//model->fifo
		scb.exp_port.connect(mdl_scb_fifo.blocking_get_export);//fifo->scoreboard
		o_agt.A_ap.connect(agt_scb_fifo.analysis_export);//output  monitor -> fifo
		scb.act_port.connect(agt_scb_fifo.blocking_get_export);//fifo->scoreboard
endfunction

使用fifo连接之后,scoreboard可以按照自己的节奏工作,而不用去适应monitor的节奏。同时也不用建立两个write函数,省去了好多麻烦。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5720055.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存