One-way communication (important)

Table of contents

1. Overview (most application scenarios in current work are one-way communication)

2. Method

3. Example

4. Summary (important)

1. Overview (most application scenarios in current work are one-way communication)

One-way communication means that the data flow from the initiator to the target is in one direction , or that the initiator and the target can only play one of the roles of producer and consumer.

In UVM, there are many types of TLM ports for a single data flow:

uvm_blocking_put_PORT
uvm_nonblocking_put_PORT
uvm_put_PORT
uvm_blocking_get_PORT
uvm_nonblocking_get_PORT
uvm_get_PORT
uvm_blocking_peek_PORT
uvm_nonblocking_peek_PORT
uvm_peek_PORT
uvm_blocking_get_peek_PORT
uvm_nonblocking_get_peek_PORT
uvm_get_peek_PORT

Among them, PORT represents three port names: port, export, imp.

According to the naming rules of UVM port names, they indicate two elements of communication:

  • Is it a blocking method (that is, you can wait for a delay)
  • What kind of communication method is it (the initiator wants to call the method declared by the target side)

The following is the specific difference between put and get:

peek and get flow in the same direction, except that the data is not taken from the buff, and the data is not removed from the buff.

2. Method

Blocking transports use the blocking prefix as part of the function name, while non-blocking transports are named nonblocking. The method type of the blocking port is task, which ensures that event waiting and delay can be realized, and the method type of the non-blocking port is function, which ensures that the method call can return immediately.
The method of blocking blocking transmission:

  • put(): Mr. initiator generates data T t, and transmits the data to target at the same time.
  • get(): The initiator obtains data T t from the target, and the data T t in the target should be consumed.
  • peek(): The initiator obtains the data T t from the target, and the data T t in the target should be retained.

nonblocking non-blocking transfer method:

  • try_put()
  • can_put()
  • try_get()
  • can_get()
  • try_peek()
  • can_peek()

3. Example

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

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

class comp1 extends uvm_component;
	uvm_blocking_put_port #(itrans) bp_port;      // #(itrans)是声明的参数类型
	uvm_nonblocking_get_port #(otrans) nbg_port;
	`uvm_component_utils(comp1)
	...
	task run_phase(uvm_phase phase);
		itrans itr;
		otrans otr;
		int trans_num = 2;
		fork
        //*************  fork 中用了两个线程***************
			begin
				for(int i = 0; i < trans_num; i++) begin
					itr = new("itr", this);
					itr.data = 'h10 + i;
					this.bp_port.put(itr);  
                   //目前只知道发送transaction,但不知道往哪个组件发送
                   //也看不出是调用组件2中的put方法
					`uvm_info("PUT", $sformatf("put itrans id: 'h%0x, data: 'h%0x", itr.id, itr.data), UVM_LOW)
				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
					`uvm_info("TRYGET", $sformatf("get otrans id: 'h%0x, data: 'h%0x", otr.id, otr.data), UVM_LOW)
				end
			end
		join
	endtask
endclass

class comp2 extends uvm_component;
	uvm_blocking_put_imp #(itrans, comp2) bp_imp;
	uvm_nonblocking_get_imp #(otrans, comp2) nbg_imp;
	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;
	endfunction
	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);
		c1.nbg_port.connect(c2.nbg_imp);
	endfunction
endclass

4. Summary (important)

  1. To know what the next transfer type is
  2. The interfaces declared by the two components must correspond, that is, the interfaces of component 1 and component 2 are both blocking_put_port  or nonblocking_get_port. . The data type to be transmitted should also be consistent.
  3. Implement put, try_get, can_get on the target side 
  4. Connect the corresponding port and imprt in the top-level environment. Note that the connection policy is initiator, and the right side is target.

Guess you like

Origin blog.csdn.net/Arvin_ing/article/details/127707025