【UVM】TLM端口的使用方法(端对端)

目录

本文目标

一、put ()模式

 代码部分

1、my_reference_model.sv文件中(紫色圆圈①)

2、my_monitor.sv文件中(紫色圆圈③)

 3、my_agent.sv文件中(紫色圆圈④)

4、my_env.sv文件中(紫色圆圈③)

5、打印结构图示

二、get ()模式

代码部分

1、my_reference_model.sv文件中(紫色圆圈①)

2、my_monitor.sv文件中(紫色圆圈④)

 3、my_agent.sv文件中(紫色圆圈③)

4、my_env.sv文件中(紫色圆圈②)

5、打印结构图示

三、fifo ()模式

代码部分

1、my_reference_model.sv文件中(紫色圆圈①)

2、my_monitor.sv文件中(紫色圆圈④)

 3、my_agent.sv文件中(紫色圆圈⑤)

4、my_env.sv文件中(紫色圆圈②、③)

5、打印结构图示


本文目标

使用 TLM端口 实现 master agent 中的 monitor组件 与 env 中的 reference model组件 互连!


UVM验证总体架构图如下所示(该部分已由红色圈出):

 一、put ()模式

put () 模式特点:port 类型的端口位于产生事务的 producer 组件(主动方)当中,import 类型的端口位于事务发送目标的 consumer 组件(被动方)当中。发送时,需要调用 port 的 put 方法来完成,需注意:该 put 方法是在 consumer 组件中定义的。

producer 发送事务时,并不知道 consumer 是否可以接收事务!

 代码部分

1、my_reference_model.sv文件中(紫色圆圈①

 在此处,reference_model 是事务的接收方,处于被动接收。

//my_reference_model扩展于uvm_component
class my_reference_model extends uvm_component;//扩展于uvm_component

//注册	
	`uvm_component_utils(my_reference_model)

//添加import(第一个参数为传输事务的类型,第二个参数为该import所在的类)
	uvm_blocking_put_imp #(my_transaction,my_reference_model) i_m2r_imp;

//实例化import对象
	function new(string name = "",uvm_component parent);
		super.new(name , parent);
		this.i_m2r_imp = new("i_m2r_imp",this);
	endfunction

//为import构建put方法(将monitor发送的事务打印出来)	
	task put(my_transaction tr);
		`uvm_info("REF_REPORT",{"\n","master agent have been sent a transaction: \n",tr.sprint()},UVM_MEDIUM)
	endtask
	
endclass

2、my_monitor.sv文件中(紫色圆圈③

//my_monitor扩展于uvm_monitor
class my_monitor extends uvm_monitor;

//添加port(参数为传输事务的类型)
	uvm_blocking_put_port #(my_transaction) m2r_port;

//实例化port对象
	function new(string name = "",uvm_component parent);
		super.new(name , parent);
		this.m2r_port = new("m2r_imp",this);
	endfunction

//将monitor发送的事务打印出来
	virtual task run_phase(uvm_phase phase);
		....//循环发送至reference_model
		`uvm_info("Monitor","Now monitor send the transaction to the reference model!",UVM_MEDIUM)

//调用put()方法发送transaction	
		this.m2r_port.put(tr);
	endtask
	
endclass

 monitor 与 reference_model 的连接最终会在 env 中完成!但是在两个组件中还有一层master_agent 阻碍,因此使用 export 端口在中间当媒介使用。

 3、my_agent.sv文件中(紫色圆圈④

//my_agent扩展于uvm_agent
class my_agent extends uvm_agent;
	...
//添加export(参数为传输事务的类型)
	uvm_blocking_put_export #(my_transaction) m_a2r_export;

//实例化export对象
	function new(string name = "",uvm_component parent);
		super.new(name , parent);
		this.m_a2r_export = new("m_a2r_export",this);
	endfunction

//连接monitor的port和master_agent的export
	virtual function void connect_phase(uvm_phase phase);
		if(is_active == UVM_ACTIVE)
			m_driv.seq_item_port.connect(m_seqr.seq_item_export);
			m_moni.m2r_port.connect(this.m_a2r_export);
	endtask
	
endclass

4、my_env.sv文件中(紫色圆圈③

//my_env扩展于uvm_env
class my_env extends uvm_env;
	...
//声明reference model句柄
	my_reference_model ref_model;

//实例化reference model对象
	virtual function void build_phase(uvm_phase phase);
		...
		ref_model = my_reference_model::type_id::create("ref_model",this);
	endfunction

//连接agent的export与reference model的import
	virtual function void connect_phase(uvm_phase phase);
		super.connect_phase(phase);
		`uvm_info("ENV","Connect the agent and reference model ...",UVM_MEDIUM)
			m_agent.m_a2r_export.connect(ref_model.i_m2r_imp);
	endfunction
	
endclass

5、打印结构图示

  二、get ()模式

get () 模式特点:consumer 是操作的主动方,从 producer 获取事务。当 producer 产生事务时不会主动发送事务至 consumer ,而是等待 consumer 发起 get 操作之后,才会进行发送。

consumer 想要获取事务时,并不知道 producer 是否有事务需要发送!

 代码部分

1、my_reference_model.sv文件中(紫色圆圈①

 在此处,reference_model 是事务的接收方,处于主动接收。

//my_reference_model扩展于uvm_component
class my_reference_model extends uvm_component;//扩展于uvm_component

//注册	
	`uvm_component_utils(my_reference_model)

//添加port(参数为传输事务的类型)
	uvm_blocking_get_port #(my_transaction) i_m2r_port;

//实例化port对象
	function new(string name = "",uvm_component parent);
		super.new(name , parent);
		this.i_m2r_port = new("i_m2r_port",this);
	endfunction

//重载run_phase任务,不断调用get()函数获取transaction
	virtual task run_phase(uvm_phase phase);
		`uvm_info("REF_MODEL_RUN","Reference model running!",UVM_MEDIUM)
        forever begin
           i_m2r_port.get(item);
           `uvm_info("REF_REPORT",{"\n","master agent have been sent a transaction: \n",item.sprint()},UVM_MEDIUM)
        end
	endtask
	
endclass

2、my_monitor.sv文件中(紫色圆圈④

//my_monitor扩展于uvm_monitor
class my_monitor extends uvm_monitor;

//添加import
	uvm_blocking_get_imp #(my_transaction,my_monitor) m2r_imp;

//添加队列,用来存储已经监测到的事务对象,避免数据丢失,因为monitor不能主动发出事务
    my_transaction tr_fifo[$];

//实例化import对象
	function new(string name = "",uvm_component parent);
		super.new(name , parent);
		this.m2r_imp = new("m2r_imp",this);
	endfunction


	virtual task run_phase(uvm_phase phase);
//将收到的transaction放入fifo中	
		tr_fifo.push_back.(tr);
	endtask

//添加get()方法	
    task get(output my_transaction s_tr);
	    while(tr_fifo.size() == 0) @(m_vif.monitor_cb);
	    s_tr = tr_fifo.pop_front();
	    `uvm_info("Monitor",{"\n","Now monitor send the transaction to the reference model: \n",s_tr.sprint()},UVM_MEDIUM)
    endtask
endclass

 monitor 与 reference_model 的连接最终会在 env 中完成!但是在两个组件中还有一层master_agent 阻碍,因此使用 export 端口在中间当媒介使用。

 3、my_agent.sv文件中(紫色圆圈③

//my_agent扩展于uvm_agent
class my_agent extends uvm_agent;
	...
//添加export(参数为传输事务的类型)
	uvm_blocking_get_export #(my_transaction) m_a2r_export;

//实例化export对象
	function new(string name = "",uvm_component parent);
		super.new(name , parent);
		this.m_a2r_export = new("m_a2r_export",this);
	endfunction

//连接monitor的port和master_agent的export
	virtual function void connect_phase(uvm_phase phase);
		if(is_active == UVM_ACTIVE)
			m_driv.seq_item_port.connect(m_seqr.seq_item_export);
			this.m_a2r_export.connect(m_moni.m2r_imp);
	endtask
	
endclass

4、my_env.sv文件中(紫色圆圈②

//my_env扩展于uvm_env
class my_env extends uvm_env;
	...
//声明reference model句柄
	my_reference_model ref_model;

//实例化reference model对象
	virtual function void build_phase(uvm_phase phase);
		...
		ref_model = my_reference_model::type_id::create("ref_model",this);
	endfunction

//连接agent的export与reference model的import
	virtual function void connect_phase(uvm_phase phase);
		super.connect_phase(phase);
		`uvm_info("ENV","Connect the agent and reference model ...",UVM_MEDIUM)
			ref_model.i_m2r_port.connect(m_agent.m_a2r_export);
	endfunction
	
endclass

5、打印结构图示

 三、fifo ()模式

fifo () 模式特点:相对于前面两种模式,fifo()模式可以在两者之间起到缓存数据的作用。在该模式下,producer 与 consumer 均为操作的主动方,fifo 为被动方。当 producer 当中有事务产生时,既可以使用 put () 操作将该事务放入 fifo 当中进行缓存,而不必等待 consumer 获取事务,所以 consumer 不会阻塞 producer 的事务发送;另一方面,当 consumer 需要事务则可以调用 get () 操作将 fifo 中的事务取出。

  代码部分

1、my_reference_model.sv文件中(紫色圆圈①

//my_reference_model扩展于uvm_component
class my_reference_model extends uvm_component;//扩展于uvm_component

//注册	
	`uvm_component_utils(my_reference_model)

//添加port(参数为传输事务的类型)
	uvm_blocking_get_port #(my_transaction) i_m2r_port;

//实例化port对象
	function new(string name = "",uvm_component parent);
		super.new(name , parent);
		this.i_m2r_port = new("i_m2r_port",this);
	endfunction

//重载run_phase任务,不断调用get()函数获取transaction
	virtual task run_phase(uvm_phase phase);
		`uvm_info("REF_MODEL_RUN","Reference model running!",UVM_MEDIUM)
        forever begin
           i_m2r_port.get(item);
           `uvm_info("REF_REPORT",{"\n","master agent have been sent a transaction: \n",item.sprint()},UVM_MEDIUM)
        end
	endtask
	
endclass

2、my_monitor.sv文件中(紫色圆圈④

//my_monitor扩展于uvm_monitor
class my_monitor extends uvm_monitor;

//添加port(参数为传输事务的类型)
	uvm_blocking_put_port #(my_transaction) m2r_port;

//实例化port对象
	function new(string name = "",uvm_component parent);
		super.new(name , parent);
		this.m2r_port = new("m2r_imp",this);
	endfunction

//将monitor发送的事务打印出来
	virtual task run_phase(uvm_phase phase);
		....//循环发送至reference_model
		`uvm_info("Monitor","Now monitor send the transaction to the reference model!",UVM_MEDIUM)

//调用put()方法发送transaction	
		this.m2r_port.put(tr);
	endtask
	
endclass

 3、my_agent.sv文件中(紫色圆圈⑤

//my_agent扩展于uvm_agent
class my_agent extends uvm_agent;
	...
//添加export(参数为传输事务的类型)
	uvm_blocking_put_export #(my_transaction) m_a2r_export;

//实例化export对象
	function new(string name = "",uvm_component parent);
		super.new(name , parent);
		this.m_a2r_export = new("m_a2r_export",this);
	endfunction

//连接monitor的export和master_agent的export
	virtual function void connect_phase(uvm_phase phase);
		if(is_active == UVM_ACTIVE)
			m_driv.seq_item_port.connect(m_seqr.seq_item_export);
			m_moni.m2r_export.connect(this.m_a2r_export);
	endtask
	
endclass

4、my_env.sv文件中(紫色圆圈②、③

//my_env扩展于uvm_env
class my_env extends uvm_env;
	...
//声明reference model句柄
	my_reference_model ref_model;

//声明fifo句柄
	uvm_tlm_analysis_fifo #(transaction) magt2ref_fifo;

//实例化reference model对象
	virtual function void build_phase(uvm_phase phase);
		...
		ref_model = my_reference_model::type_id::create("ref_model",this);
	endfunction

//实例化fifo
	function new(string name = "" , uvm_component parent);
		super.new(name , parent);
		magt2ref_fifo = new("magt2ref",this);
	endfunction

	virtual function void connect_phase(uvm_phase phase);
		super.connect_phase(phase);
//连接agent与fifo
		`uvm_info("ENV","Connect the agent to fifo ...",UVM_MEDIUM)
			m_agent.m_a2r_export.connect(this.magt2ref_fifo.blocking_put_export); 
//连接reference_model与fifo      
 		`uvm_info("ENV","Connect the reference model to fifo ...",UVM_MEDIUM)
			ref_model.i_m2r_port.connect(this.magt2ref_fifo.blocking_get_export);        
	endfunction
	
endclass

5、打印结构图示


  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的隼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值