[Verilog] task, function

준치·2022년 2월 23일

[Verilog]

목록 보기
8/9

테스트 벤치에서 사용하는것같다.

task

코드의 반복을 줄이기 위해 사용한다.

사용 방법은 task와 endtask로 감싸서 사용한다.

행위 수준 문장만 포함 할 수 있다.

  • 특징
    내부에 다른 task와 function을 사용할 수 있다.
    non-zero 시뮬레이션 시간에 수행될 수 있다.
    delay, 사건 또는 타이밍 제어 문장을 포함할 수 있다.
    input, output, inout을 다수 가지거나 하나도 가지지 않을 수 있다.
    값을 되돌릴 수 없지만, output과 input을 통해서 여러 개의 값을 전달할 수 있다.

ex. task의 입출력 인수

// task bitwise_oper를 포함하는 operation이라는 모듈을 정의
module operation;
....
....
parameter delay = 10;
reg [15:0] A, B;
reg [15:0] AB_AND, AB_OR, AB_XOR;

always@(A or B)
begin
    // task bitwise_oper를 호출. 2개의 입력 A, B를 제공하고
    // 3개의 출력 인자 AB_AND, AB_OR, AB_XOR를 받는다.
    // 인자는 task 선언과 같은 순서로 지정되어야 한다.
	bitwise_oper(AB_AND, AB_OR, AB_XOR, A, B)
end
....
....
// task bitwise_oper의 정의
task bitwise_oper(
output [15:0] ab_and, ab_or, ab_xor, // task의 output
input  [15:0] a, b // task의 input
); 
begin
	#delay ab_and = a & b;
    	   ab_or  = a | b;
    	   ab_xor = a ^ b;
end
endtask
...
endmodule
    

만약 같은 task를 동시에 호출할 때는 automatic을 사용해준다.
ex. 재진입 task

// 재진입 task를 포함한 모듈
// 두개의 clk이 있고, clk2는 clk의 두배 주기로 동작하며 동기적이다.
module top;
reg [15:0] cd_xor, ef_xor; // top 모듈의 변수
reg [15:0] c, d, e, f; // top 모듈의 변수
-
task automatic bitwise_xor(
	output [15:0] ab_xor,
   input  [15:0] a, b
);
begin
	#delay ab_and = a & b;
   	  	   ab_or  = a | b;
           ab_xor = a ^ b;
end
endtask
...
-
// 아래 두개의 always 블록은 clk의 postive edge에 동시에
// bitwise_xor task를 호출할 것이다.
// automatic을 사용하여 호출이 올바르게 동작한다.
always@(posedge clk)
	bitwise_xor(ef_xor, e, f);
-
always@(posedge clk2)
	bitwise_xor(cd_xor, c, d);
-
-
endmodule

function

task와 마찬가지로 반복을 줄이기 위해 사용한다.

사용 방법은 function과 endfunction로 감싸서 사용한다.

  • 특징
    다른 function을 사용할 수 있지만, 다른 task는 사용 할 수 없다.
    항상 시뮬레이션 시간 0에 수행된다.
    어떤 delay, 사건 또는 타이밍 제어 문장을 포함할 수 없다.
    적어도 하나 이상의 input을 가져야 한다.
    조합회로 모델링(합성)이 가능하다.

    ex. shifter

    // shift함수를 포함한 모듈을 정의
    module shifter;
    ...
    `define LEFT_SHIFT 1'b0
    `define RIGHT_SHIFT 1'b1
    reg [31:0] addr, left_addr, right_addr;
    reg control;
    
    // 새로운 주소값이 올 때 마다 시프트값이 계산된다.
    always@(addr)
    begin
    	// 좌측과 우측 자리 이동을 위한 정의된 함수를 호출
       left_addr  = shift(addr, `LEFT_SHIFT);
       right_addr = shift(addr, `RIGHT_SHIFT);
    end
    ...
    ...
    // shift 함수
    function [31:0] shift(
    	input [31:0] address,
       input		 control
       );
    begin
    	// 제어 신호에 의해 출력값이 결정된다.
       shift = (control == `LEFT_SHIFT) ? (address << 1) : (address >> 1);
    end
    endfunction
    ...
    ...
    endmodule

    task와 마찬가지로 동시에 호출될 경우에 automatic을 붙여준다.

    Reference

    [1] SAMIR PALNITKAR, ⌜Verilog HDL 디지털 설계와 합성의 길잡이, 2th Edition⌟ , chapter 8
profile
설계 엔지니어 지망생

0개의 댓글