systemverilog에서 task, function을 사용하다 보면 block에서 block으로 값을 넘겨 줄 때가 있습니다.
기존에 포스팅한 것과 같이 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를 사용하기 위해서는 붙여줘야 한다는 군요...
'language > Verilog' 카테고리의 다른 글
[systemverilog] assert, property (0) | 2021.02.21 |
---|---|
[systemverilog] always_comb, always_ff, always_latch (0) | 2021.02.21 |
[verilog] system function list (0) | 2021.02.06 |
[systemverilog] enum 사용법 (0) | 2021.02.02 |
[verilog] >>, >>>, <<, <<< 연산자 (2) | 2021.01.31 |
댓글