본문 바로가기
language/Verilog

[systemverilog] pass by reference

by 파란하늘코더 2021. 2. 21.
반응형

systemverilog에서 task, function을 사용하다 보면 block에서 block으로 값을 넘겨 줄 때가 있습니다.

 

leehc257.tistory.com/39 

 

[systemverilog] automatic keyword

예전 블로그에서 automatic이 뭔지 몰라 정리를 했었던 적이 있습니다 blog.naver.com/ddacksal/222029970829 [Day 49] systemverilog 공부 - 8 (automatic, static, initialize, datatype) 새로 산 책에 제목에..

leehc257.tistory.com

기존에 포스팅한 것과 같이 automatic이라는 keyword와 같이 사용해야 하는 방식을 정리합니다.

 

우선 아래와 같은 code가 있다고 하면

 

initial begin
    clk = 1'b0;
    fork
        data_gen(data);
        data_read(data);
    join
end
always #(`Clock_period/2)  clk = !clk;

task data_gen(output logic [2:0] wdata);
        #100  data    =   3'd1;
        #100  data    =   3'd2;
        #100  data    =   3'd3;
        #100  data    =   3'd4;
        #100;
endtask

task data_read(logic [2:0] rdata);
    for(integer i =0;i<4;i++)begin
       #100
       $display($stime, "read : 0x%h", rdata);
    end
endtask

여기서 원하는 내용은 data_gen에서 생성된 1 2 3 4 라는 신호가 data_read에 옮겨져서

 

그대로 display라는 system function을 호출 하는 것 입니다.

 

하지만 결과를 보면 

이렇게 제대로 된 값이 나오지를 않습니다.

 

원인은 fork~join 구문에서 호출될 당시에 선언된 data 값이 복사되어 data_read라는 task에 전달이 되는데

 

이때 data는 아무 값도 없기 때문에 dummy 값으로 전달이 되고

 

이 dummy 값을 가지고 4번을 display함수의 입력으로 사용하게 됩니다.

 

이를 다시 timing 으로 표현을 하면

이와 같은 모습입니다.

 

여기서 중요한건 task가 호출되는 시점에 data가 복사가 이루어진다는 점이고,

 

우리가 하고싶은 data를 꾸준히 따라가고 싶을때는 C++ 에서의 주소값을 참조하는 식의 &를 붙여주면 됩니다.

 

systemverilog에서는 ref라는 keywork를 붙여주면 되고,

 

아래와 같이 구문을 수정해주면 됩니다.


task automatic data_gen(ref logic [2:0] wdata);
        #100  data    =   3'd1;
        #100  data    =   3'd2;
        #100  data    =   3'd3;
        #100  data    =   3'd4;
        #100;
endtask
task automatic data_read(ref
logic [2:0] rdata);
    for(integer i =0;i<4;i++)begin
       #100
       $display($stime, "read : 0x%h", rdata);
    end
endtask

다시 simulation을 돌리면 아래와 같이 잘 결과가 나오는 것을 확인 할 수가 있습니다.

automatic의 경우는 ref를 사용하기 위해서는 붙여줘야 한다는 군요...

 

댓글