UVM学习笔记(5)

学习目标

UVM入门和进阶部分5

学习内容

1.TLM是一种基于事务的通信方式,将模块内的计算和模块之间的通信从时间跨度方面剥离开了

2.提高系统模型的仿真性能,两方面:建模自身的运算优化、模型之间的通信优化

3.TLM通信的两个通信对象:
initiator/target:通信请求方、通信响应方
producer/consumer:数据产生、数据流向

4.TLM通信步骤:
分辨出initiator/target和producer/consumer
在target中实现TLM通信方法
在两个对象中创建TLM端口
在更高层次中将两个对象的端口进行连接

5.从数据流向来看,传输方向可以分为单向和双向

6.端口类型划分为三种:
port----经常作为initiator的发起端,initiator凭借port才可以访问target的TLM通信方法
export—作为initiator/target中间层次的端口
imp—只能作为target接收request的末端

7.port/export作为request发起方,需要指定transaction类型参数,而声明imp作为request接收方,不但需要指定transaction类型,也需要指定它所在的component类型

8.建立TLM通信的详细步骤:
定义TLM传输中的数据类型
分别在各个层次的component中声明和创建TLM端口对象
通过connect()函数完成端口之间的连接
在imp端口类中实现需要提供给initiator的可调方法

9.阻塞端口的方法类型为task,这保证了可以实现事件等待和延时
非阻塞端口的方式类型为function,这确保了方法调用可以立即返回

10.blocking阻塞传输的方法包含:
put():initiator先生成数据T t,同时将该数据传送至target
get():initiator从target获取数据,而target中的该数据则应消耗
peek():initiator从target获取数据,而target中的该数据则应保留

try_put()、can_put()、try_get()、can_get()、try_peek()、can_peek()
try_xxx函数可以发送或者获取数据,执行成功返回1,失败返回0
can_xxx函数,先试探target是否可以接收数据,如果可以,再通过try_xxx发送,提高数据发送的成功率

11.单向通信示例:(不懂看视频)

class itrans extends uvm_transaction;
	int  id;
	int  data;
	...
endclass

class otans extends uvm_transaction;
	int  id;
	int  data;
	...
endclass

class comp1 extends uvm_component;
	uvm_blocking_put_port  #(itrans) bp_port;
	uvm_nonblocking_get_port  #(otrans) nbg_port;
	'uvm_component_utils(comp1)
	...
	task run_phase(uvm_phase phase)
		itrans itr;
		otraans otr;
		int trans_num=2;
		fork
			begin
				for(int i=0;i<trans_num;i++) begin
					itr=new("itr",this);
					itr.id=i;
					itr.data='h10+i;
					this.bp_port.put(itr);
					end
			end
			begin
				for(int j=0;j<trans_num;j++) begin
					forever begin
						if(this.nbg_port.try_get(otr)==1) break;
						else  #1ns;
					end
			end
		join

class comp2 extends uvm_component;
	uvm_blocking_put_imp  #(itrans,comp2) bp_port;
	uvm_nonblocking_get_imp  #(otrans,comp2) nbg_port;
	itrans itr_q[$];
	'uvm_component_utils(comp2)
	...
	task put(itrans t)
		itr_q.push_back(t);
	endtask
	
	function bit try_get(output otrans t);
		itrans i;
		if(itr_q.size!=0) begin
			i=itr_q.pop_front();
			t=new("t",this);
			t.id=i.id;
			t.data=i.data<<8;
			return  1;
		end
		else
			return 0;
		
		function bit can_get();
			if(itr_q.size()!=0)  return 1;
			else  return 0;
		endfunction
endclass

class env1 extends uvm_env;
	comp1 c1;
	comp2 c2;
	'uvm_component_utils(env1)
	...
	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		c1=comp1::type_id::create("c1",this);
		c2=comp2::type_id::create("c2",this);
	endfunction

	function void connect_phase(uvm_phase phase);
		super.connect_phase(phase);
		c1.bp_port.connect(c2.bp_imp);
		c2.nbg_port.connect(c2.nbg_imp);
	endfunction:connect_phase
endclass

12.双向端口按照通信握手方式可以分为:
transport双向通信方式
master和slave双向通信方式

13.transport端口通过transport()方法,可以在同一方法调用过程中完成REQ和RSP的发出和返回

14.master和slave的通信方式必须分别通过put、get和peek的调用,使用两个方法才可以完成一次握手通信

15.双向通信transport

class itrans extends uvm_transaction;
	int  id;
	int  data;
	...
endclass

class otans extends uvm_transaction;
	int  id;
	int  data;
	...
endclass

class comp1 extends uvm_component;
	uvm_blocking_transport_port  #(itrans,otrans) bt_port;
	'uvm_component_utils(comp1)
	...
	task run_phase(uvm_phase phase)
		itrans itr;
		otraans otr;
		int trans_num=2;
		for(int i=0;i<trans_num;i++) begin
			itr=new("itr",this);
			itr.id=i;
			itr.data='h10+i;
			this.bp_port.put(itr);
			end
	endtask

class comp2 extends uvm_component;
	uvm_blocking_transport_imp  #(itrans,otrans,comp2) bt_imp;
	'uvm_component_utils(comp2)
	...
	task transport(itrans req,output otrans rsp);
		rsp=new("rsp",this);
		rsp.id=req.id;
		rsp.data=req.data<<8;
	endtask
endclass

class env1 extends uvm_env;
	comp1 c1;
	comp2 c2;
	'uvm_component_utils(env1)
	...
	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		c1=comp1::type_id::create("c1",this);
		c2=comp2::type_id::create("c2",this);
	endfunction

	function void connect_phase(uvm_phase phase);
		super.connect_phase(phase);
		c1.bt_port.connect(c2.bp_imp);
	endfunction:connect_phase
endclass

16.多向通信仍然是两个组件之间的通信
如果initiator和target之间的相同TLM端口数目超过一个时的处理解决方法

17.多向通信

'uvm_blocking_put_imp_decl(_p1)
'uvm_blocking_put_imp_decl(_p2)

class comp1 extends uvm_component;
	uvm_blocking_put_port  #(itrans) bp_port1;
	uvm_blocking_put_port  #(itrans) bp_port2;
	'uvm_component_utils(comp1)
	...
	task run_phase(uvm_phase phase)
		itrans itr1,itr2;
		otraans otr;
		int trans_num=2;
		fork
			for(int i=0;i<trans_num;i++) begin
				itr1=new("itr1",this);
				itr1.id=i;
				itr1.data='h10+i;
				this.bp_port1.put(itr1);			//这里调用的是put,非put_p1
				end
			for(int i=0;i<trans_num;i++) begin
				itr2=new("itr2",this);
				itr2.id=i;
				itr2.data='h10+i;
				this.bp_port2.put(itr2);
				end
		join
	endtask
enclass

class comp2 extends uvm_component;
	uvm_blocking_put_imp_p1  #(itrans,comp2) bt_imp_p1;
	uvm_blocking_put_imp_p2  #(itrans,comp2) bt_imp_p2;
	itrans itr_q[$];
	semaphore key;
	'uvm_component_utils(comp2)
	...
	task put_p1(itrans t);		//方法为put_p1
		key.get();
		itr_q.push_back(t);
		key.put();
	endtask
	
	task put_p2(itrans t);
		key.get();
		itr_q.push_back(t);
		key.put();
	endtask
endclass

class env1 extends uvm_env;
	comp1 c1;
	comp2 c2;
	'uvm_component_utils(env1)
	...
	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		c1=comp1::type_id::create("c1",this);
		c2=comp2::type_id::create("c2",this);
	endfunction

	function void connect_phase(uvm_phase phase);
		super.connect_phase(phase);
		c1.bt_port1.connect(c2.bp_imp_p1);
		c2.bt_port2.connect(c2.bp_imp_p2);
	endfunction:connect_phase
endclass

用户只需要在例化多个imp端口的组件中实现不同名称的方法,使其与对应imp类型名保持一致
而对于port端口,不需要关心调用的方法的名称

18.TLM_fifo
uvm_tlm_fifo类是一个新组件,它继承于uvm_component类,而且已经预先内置了多个端口以及实现了多个对应方法供用户使用

学习问题

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值