UVM通信

3.UVM中的TLM1.0通信

TLM1.0

1.

如果要在两个uvm_component之间通信,如一个monitor向一个scoreboard传递一个数据,你可以采用下图中的方法:
在这里插入图片描述

当然也可以从uvm_object派生出一个参数类config_object,在此类中有monitor要传给scoreboard的变量。在base_test中,实例化这个config_object,并将其指针通过config_db#(config_object)::set传递scoreboard和monitor。当monitor要和scoreboard通信时,只要把此config_object中相应变量的值改变即可。scoreboar中则监测变量值的改变,监测到之后做相应动作。

但是以上这种方式还是存在风险,即不能保证某一个从base_test派生而来的类会不会改变这个config_object类中某些变量的值,而且还缺少对阻塞和非阻塞情况的考虑。

解决这些问题最好的办法就是在monitor和scoreboard之间专门建立一个通道,让信息只能在这个通道内流动,scoreboard也只能从这个通道中接收信息,这样几乎就可以保证scoreboard中的信息只能从monitor中来,而不能从别的地方来;同时赋予这个通道阻塞或者非阻塞等特性。UVM中的各种端口就可以实现这种功能。

2.

TLM是Transaction Level Modeling(事务级建模)的缩写,一个transaction就是把具有某一特定功能的一组信息封装在一起而成为的一个类。

首先要理解get、put和transport操作,即:

  • put:通信的发起者A把一个transaction发送给B;
  • get:A向B索取一个transaction;
  • transport:一次put操作加一次get操作,即做request - response操作。

3.

UVM通过端口PORT和EXPORT来实现对TLM的支持,常用的PORT有:

uvm_blocking_put_port#(T);
uvm_nonblocking_put_port#(T);
uvm_put_port#(T);
uvm_blocking_get_port#(T);
uvm_nonblocking_get_port#(T);
uvm_get_port#(T);
uvm_blocking_peek_port#(T);
uvm_nonblocking_peek_port#(T);
uvm_peek_port#(T);
uvm_blocking_get_peek_port#(T);
uvm_nonblocking_get_peek_port#(T);
uvm_get_peek_port#(T);
uvm_blocking_transport_port#(REQ, RSP);
uvm_nonblocking_transport_port#(REQ, RSP);
uvm_transport_port#(REQ, RSP);

常用的EXPORT有:

uvm_blocking_put_export#(T);
uvm_nonblocking_put_export#(T);
uvm_put_export#(T);
uvm_blocking_get_export#(T);
uvm_nonblocking_get_export#(T);
uvm_get_export#(T);
uvm_blocking_peek_export#(T);
uvm_nonblocking_peek_export#(T);
uvm_peek_export#(T);
uvm_blocking_get_peek_export#(T);
uvm_nonblocking_get_peek_export#(T);
uvm_get_peek_export#(T);
uvm_blocking_transport_export#(REQ, RSP);
uvm_nonblocking_transport_export#(REQ, RSP);
uvm_transport_export#(REQ, RSP);

UVM中端口互连

1.

UVM中使用connect函数来建立端口的连接,如A要和B通信(A是发起者),那么可以这么写:

A.port.connect(B.export)

注意顺序,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

B的代码为:

class B extends uvm_component;
	`uvm_component_utils(B)
	uvm_blocking_put_export#(my_transaction) B_export;
endclass
function void B::build_phase(uvm_phase phase);
	super.build_phase(phase);
	B_export = new("B_export", this);
endfunction
task B::main_phase(uvm_phase phase);
endtask

在env中建立两者之间的连接:

class my_env extends uvm_env;
	A A_inst;
	B B_inst;
	virtual function void build_phase(uvm_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

但是仿真会报错,因为这里只是完成了端口的连接,但是并没有对transaction进行处理,PORT和EXPORT只是个闸口,而在EXPORT端口之后的处理才是重点,而完成这种后续处理的端口叫做IMP。

2.

UVM中的IMP有:

uvm_blocking_put_imp#(T, IMP);
uvm_nonblocking_put_imp#(T, IMP);
uvm_put_imp#(T, IMP);
uvm_blocking_get_imp#(T, IMP);
uvm_nonblocking_get_imp#(T, IMP);
uvm_get_imp#(T, IMP);
uvm_blocking_peek_imp#(T, IMP);
uvm_nonblocking_peek_imp#(T, IMP);
uvm_peek_imp#(T, IMP);
uvm_blocking_get_peek_imp#(T, IMP);
uvm_nonblocking_get_peek_imp#
  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值