其他分享
首页 > 其他分享> > UVM入门与进阶学习笔记12——TLM2通信(2)

UVM入门与进阶学习笔记12——TLM2通信(2)

作者:互联网

目录


同步通信元件

uvm_event

uvm_event类相比于event:

uvm_event应用

class edata extends uvm_object;
	int data;
	`uvm_object_utils(edata)
	...
endclass
class ecb extends uvm_event_callback;
	`uvm_object_utils(ecb)
	...
	function bit pre_trigger(uvm_event e, uvm_object data=null);
		`uvm_info("EPRETRIG", $sformatf("before trigger event %s", e.get_name()), UVM_LOW)
		return 0;
	endfunction
	function void post_trigger(uvm_event e, uvm_object data=null);
		`uvm_info("EPOSTTRIG", $sformatf("after trigger event %s", e.get_name()), UVM_LOW)
	endfunction
endclass
class comp1 extends uvm_component;
	uvm_event e1;
	`uvm_component_utils(comp1)
	...
	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		e1 = uvm_event_pool::get_global("e1"); //notice
	endfunction
	task run_phase(uvm_phase phase);
		edata d = new();
		ecb cb = new();
		d.data = 100;
		#10ns;
		e1.add_callback(cb);
		e1.trigger(d);
		`uvm_info("ETRIG", $sformatf("trigger sync event at %t ps", $time), UVM_LOW)
	endtask
endclass
class comp2 extends uvm_component;
	uvm_event e1;
	`uvm_component_utils(comp2)
	...
	function void build_phase(uvm_phase phase);
		super.build_phase(phase)
		e1 = uvm_event_pool::get_global("e1"); //若没有e1会自动创建
	endfunction
	task run_phase(uvm_phase phase);
		uvm_object tmp;
		edata d;
		`uvm_info("ESYNC", $sformatf("wait sync event at %t ps", $time), UVM_LOW)
		e1.wait_trigger_data(tmp);  //等待触发同时等待数据
		void'($cast(d, tmp));  //父类转为子类
		`uvm_info("ESYNC", $sformatf("get data %0d after sync at %t ps", d.data, $time), UVM_LOW)
	endtask
endclass
class env1 extends uvm_env;
	comp1 c1;
	comp2 c2;
	`uvm_component_utils(env1)
	...
endclass
输出结果:
UVM_INFO @0: reporter [RNTST] Running test test1...
UVM INFO @0: uvm_test_top.env.c2 [ESYNC] wait sync event at 0 ps
UVM INFO @10000: reporter [EPRETRIG] before trigger event e1
UVM INFO @10000: reporter [EPOSTRIG] after trigger event e1
UVM INFO @10000: uvm_test_top.env.c1 [ETRIG] trigger sync event at 10000 ps
UVM INFO @10000: uvm_test_top.env.c2 [ESYNC] get data 100 after sync at 10000 ps

uvm_event总结

uvm_barrier

typedef uvm_object_string_pool #(uvm_barrier) uvm_barrier_pool;
typedef uvm_object_string_pool #(uvm_event #(uvm_object)) uvm_event_pool;

uvm_barrier应用

class comp1 extends uvm_component;
	uvm_barrier b1;
	`uvm_component_utils(comp1)
	...
	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		b1 = uvm_barrier_pool::get_global("b1");  //类似于uvm_event
	endfunction
	task run_phase(uvm_phase phase);
		#10ns;
		`uvm_info("BSYNC", $sformatf("c1 wait for b1 at %0t ps", $time), UVM_LOW)
		b1.wait_for();  //等待阈值满足则立即执行下一行
		`uvm_info("BSYNC", $sformatf("c1 is activated at %0t ps", $time), UVM_LOW)
	endtask
endclass
class comp2 extends uvm_component;
	uvm_barrier b1;
	`uvm_component_utils(comp2)
	...
	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		b1 = uvm_barrier_pool::get_global("b1");
	endfunction
	task run_phase(uvm_phase phase);
		#20ns;
		`uvm_info("BSYNC", $sformatf("c2 wait for b1 at %0t ps", $time), UVM_LOW)
		b1.wait_for();
		`uvm_info("BSYNC", $sformatf("c2 is activated at %0t ps", $time), UVM_LOW)
	endtask
endclass
class env1 extends uvm_env;
	comp1 c1;
	comp2 c2;
	uvm_barrier b1;
	`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);	
		b1 = uvm_barrier_pool::get_global("b1");
	endfunction
	task run_phase(uvm_phase phase);
		b1.set_threshold(3); //设置等待阈值为3
		`uvm_info("BSYNC", $sformatf("env set b1 threshold %d at %0t ps", b1.get_threshold(), $time), UVM_LOW)
		#50ns;
		b1.set_threshold(2);
		`uvm_info("BSYNC", $sformatf("env set b1 threshold %d at %0t ps", b1.get_threshold(), $time), UVM_LOW)
	endtask
endclass
输出结果:
UVM_INFO @0: reporter [RNTST] Running test test..
UVM_INFO @0: uvm_test_top.env [BSYNC] env set b1 threshold 3 at 0ps
UVM_INFO @ 10000: uvm_test_top.env.c1 [BSYNC] c1 wait for b1 at 10000 ps
UVM_INFO @ 20000: uvm_test_top.env.c2 [BSYNC] c2 wait for b1 at 20000 ps
UVM_INFO @ 50000: uvm_test_top.env [BSYNC] env set b1 threshold 2 at 50000 ps
UVM_INFO @ 50000: uvm_test_top.env.c1 [BSYNC] c1 is activated at 50000 ps
UVM_INFO @ 50000: uvm_test_top.env.c2 [BSYNC] c2 is activated at 50000 ps

uvm_callback

uvm_callback应用

class edata extends uvm_object;
	int data;
	`uvm_object_utils(edata)
	...
endclass
class cb1 extends uvm_callback;
	`uvm_object_utils(cb1)
	...
	virtual function void do_trans(edata d);
		d.data = 200;
		`uvm_info("CB", $sformatf("cb1 executed with data %0d", d.data), UVM_LOW)
	endfunction
endclass
class cb2 extends cb1;
	`uvm_object_utils(cb2)
	...
	function void do_trans(edata d); //这里不需要super,因为do_trans相当于override
		d.data = 300;
		`uvm_info("CB", $sformatf("cb2 executed with data %0d", d.data), UVM_LOW)
	endfunction
endclass
class comp1 extends uvm_component;
	`uvm_component_utils(comp1)
	`uvm_register_cb(comp1, cb1)  //comp1和cb1进行关联(注册/绑定)
	...
	task run_phase(uvm_phase phase);
		edata d = new();
		d.data = 100;
		`uvm_info("RUN", $sformatf("proceeding data %0d", d.data), UVM_LOW)
		`uvm_do_callbacks(comp1, cb1, do_trans(d)) //插入callback
	endtask
endclass
class env1 extends uvm_env;
	comp1 c1;
	cb1 m_cb1;
	cb2 m_cb2;
	`uvm_component_utils(env1)
	function new(string name, uvm_component parent);
		super.new(name, parent);
		m_cb1 = new("m_cb1");  //例化callback
		m_cb2 = new("m_cb2");
	endfunction
	function void build_phase(uvm_phase phase);
		super.build_phase(phase);
		c1 = comp1::type_id::create("c1", this);
		uvm_callbacks #(comp1)::add(c1, m_cb1);  //顶层添加callback
		uvm_callbacks #(comp1)::add(c1, m_cb2);
	endfunction
endclass
输出结果
UVM_INFO @0: reporter [RNTST] Running test test1...
UVM_INFO @0: uvm_test_top.erv.c1 [RUN] proceeding data 100
UVM_INFO @0: reporter [CB] cb1 executed with data 200
UVM_INFO @0: reporter [CB] cb2 executed with data 300

uvm_callback总结:

标签:TLM2,12,进阶,callback,uvm,phase,data,event,UVM
来源: https://blog.csdn.net/weixin_41979380/article/details/122616995