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函数,省去了好多麻烦。

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UVM(Universal Verification Methodology)是一种用于验证硬件设计的标准方法学。在UVM中,驱动(Driver)和序列(Sequence)是两个重要的构建块,用于驱动测试向DUT(Design Under Test)发送数据。 驱动是一个UVM组件,用于将测试向DUT发送数据。驱动接收来自序列的数据,并将其转换为适当的信号或数据格式,然后将其传递给DUT。驱动通常与监控(Monitor)组件一起使用,后者用于捕获DUT的输出并进行验证。 序列是一个UVM组件,用于生成测试向DUT发送的数据序列。序列可以定义为一系列事务(Transaction),每个事务包含要发送到DUT的数据和相应的控制信息。序列可以按照特定的顺序发送事务,也可以根据需要进行重复或循环。 驱动和序列之间的通信是通过UVM提供的TLM(Transaction Level Modeling)接口进行的。序列通过调用驱动的TLM接口将数据传递给驱动,并等待驱动完成传输。 以下是一个简单的UVM驱动和序列的示例: ```systemverilog class my_sequence extends uvm_sequence#(my_transaction); // 定义sequence的行为和生成事务 // ... endclass class my_driver extends uvm_driver#(my_transaction); // 定义driver的行为和处理接收到的事务 // ... endclass ``` 在测试中,可以创建一个序列并将其连接到驱动,然后通过启动序列来驱动测试。驱动将接收到的事务转换为适当的信号或数据格式,并将其传递给DUT。 注意,以上只是一个简单的示例,实际使用中可能涉及更复杂的行为和功能。UVM提供了丰富的功能和方法,可用于更高级的验证需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值