일방적인 의사소통(중요)

목차

1. 개요 (현재 작업 중인 대부분의 적용 시나리오는 단방향 통신입니다.)

2. 방법

3. 예시

4. 요약(중요)

1. 개요 (현재 작업 중인 대부분의 적용 시나리오는 단방향 통신입니다.)

단방향 통신이란 개시자에서 대상으로의 데이터 흐름이 한 방향 이거나 개시자와 대상이 생산자와 소비자의 역할 중 하나만 수행할 수 있음을 의미합니다 .

UVM에는 단일 데이터 흐름을 위한 다양한 유형의 TLM 포트가 있습니다.

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

그 중 PORT는 포트, 내보내기, 임프의 세 가지 포트 이름을 나타냅니다.

UVM 포트 이름의 명명 규칙에 따르면 이는 두 가지 통신 요소를 나타냅니다.

  • 차단 방법인가요?(즉, 지연을 기다릴 수 있습니다.)
  • 어떤 종류의 통신 방식인가(Initiator는 Target 측에서 선언한 방식을 호출하려고 함)

다음은 put과 get의 구체적인 차이점입니다.

데이터가 버프에서 가져오지 않고 버프에서 데이터가 제거되지 않는다는 점을 제외하면 엿보기와 흐름은 같은 방향으로 진행됩니다.

2. 방법

차단 전송은 함수 이름의 일부로 차단 접두사를 사용하는 반면, 비차단 전송은 비차단으로 명명됩니다. 블로킹 포트의 메소드 타입은 태스크(task)로 이벤트 대기와 지연이 구현될 수 있도록 하며, 비블로킹 포트의 메소드 타입은 함수(function)로 메소드 호출이 즉시 반환될 수 있도록 보장한다.
차단 전송 차단 방법:

  • put(): 개시자 씨는 데이터 T t를 생성하고 동시에 데이터를 대상으로 전송합니다.
  • get(): 개시자는 대상으로부터 데이터 T t 를 획득하고, 대상에 있는 데이터 T t 를 소비해야 합니다.
  • peek(): 개시자는 대상으로부터 데이터 T t 를 획득하고 대상의 데이터 T t 는 유지되어야 합니다.

비차단 비차단 전송 방법:

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

3. 예시

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. 요약(중요)

  1. 다음 전송 유형이 무엇인지 확인하려면
  2. 두 구성 요소에서 선언한 인터페이스는 일치해야 합니다. 즉, 구성 요소 1과 구성 요소 2의 인터페이스는 모두 Blocking_put_port  또는 nonblocking_get_port입니다. . 전송되는 데이터 유형도 일관되어야 합니다.
  3. 대상 측에 put, try_get, can_get을 구현합니다. 
  4. 최상위 환경에서 해당 포트와 import를 연결하는데, 연결 정책은 initiator, 오른쪽이 target이라는 점 참고하세요.

추천

출처blog.csdn.net/Arvin_ing/article/details/127707025