verilog의 task와 function syntax에 관한 포스팅입니다. 겨울방학 때 verilog 스터디를 끝내고 싶었는데, 3월까지 지연이 됐네요. 3월 16일 전까지 마무리하는 게 목표입니다.
verilog에는 function과 task가 있습니다. function은 C나 python에서 쓰는 function과 유사하지만, task는 다른 언어와 equivalent한 개념이 없습니다. 그래서 task는 따로 공부해줘야 합니다.
function과 task를 사용하는 이유는 2가지 입니다.
첫 번째는 긴 module에서 반복적인 작업을 task & function으로 대체할 수 있습니다.
두 번쨰는 RTL source code의 가독성을 높여줍니다.
우선 fucntion과 task의 차이점을 알아보겠습니다.
Functions | Tasks |
timing과 관련이 없다.(항상 0 simulation time에 실행된다.) | timing과 관련이 있다.(0 simulation time이 아닐때도 실행된다.) |
function내에서 다른 function을 호출할 수 있지만, task는 호출할 수 없다. | function, task 모두 호출할 수 있다. |
dalay, timing control statement를 포함할 수 없다. | dalay, timing control statement를 포함할 수도 있다. |
적어도 하나의 input을 가져야한다. 여러 개의 input을 가질 수 도있다. | input, output을 하나도 가지지 않을 수도 있고, 여러 개 가질 수도 있다. |
항상 single value를 return한다. output이나 inout을 가질 수 없다.(function name이 wire형으로 반환된다.) | value를 return하지는 않지만, output, inout을 통해 여러 값을 전달할 수 있다. |
위 표에서 나타난 차이점을 보면 알겠지만, task가 function보다 좀더 큰 범주에 속합니다.
Note
- task와 function 둘 다 module 내에서 정의되어야 한다.
- task와 fucntion은 initial statement와 always statement를 포함할 수 없다.
이제 Task를 자세히 알아보겠습니다.
Task
task의 선언에 관한 docs가 있지만, 가독성이 떨어지고 보기싫어서 예시를 통해 알아보겠습니다.
module operation;
parameter delay = 10;
reg [15:0] A, B;
reg [15:0] AB_AND, AB_OR, AB_XOR;
always @(A or B)
begin
bitwise_oper(AB_AND, AB_OR, AB_XOR, A, B);
end
task bitwise_oper;
output [15:0] ab_and, ab_or, ab_xor;
input [15:0] a, b;
begin
#delay ab_and = a & b;
ab_or = a | b;
ab_xor = a ^ b;
end
endtask
endmodule
위 코드를 보면 module 하단부에 task가 선언된 것을 볼 수 있습니다. module ~ endmodule과 같이, task 또한 task ~ endtask를 써서 선언합니다.
task name에서 input, output을 선언하지않고 task 내에서 input, output을 선언했습니다.
task의 특이한 점은 hard 코딩이 가능하다는 점입니다. 즉 task 내에 input을 선언하지 않아도, module 내의 변수를 바꿀 수 있습니다. 하지만 제가 배우는 교수님은 이러한 코딩 스타일을 권하지 않는다고 합니다. task단에서 무슨 일이 일어나는지도 모르는데 변수가 바뀌고, 디버깅이 어렵기 때문입니다.
Task - Automatic task
automatic task란 두 task를 동시에 operate할 수 있는 task입니다. 동시에 operate할 수 없는 task는 static task라 합니다.
다음과 같이 task 선언시 automatic이라는 키워드를 붙여서 선언합니다.
task automatic bitwise_xor;
...
...
...
endtask
always @(posedge clk)
bitwise_xor(ef_xor, e, f);
always @(posedge clk)
bitwise_xor(cd_xor, c, d);
// automatic task로 선언했으므로 두 개의 task가 동시에 실행됩니다.
이번에는 function을 자세히 알아보겠습니다.
Function
이번에도 function의 선언에 관한 docs 대신 예시를 통해 알아보겠습니다.
module parity;
...
reg [31:0] addr;
reg parity;
always @(addr)
begin
parity = calc_parity(addr);
end
// function 선언
function calc_parity;
input [31:0] address;
begin
calc_parity = ^address;
end
endfunction
endmodule
위의 예시 code에서 calc_parity라는 function을 선언하였습니다. 위 표에서 function은 항상 single value를 return 한다고 했는데, output이 선언되어있지 않습니다. 왜 그런걸까요?
그런 바로 function을 선언하면 function name이 명시적으로 wire로 선언되기 때문입니다. 그래서 function statement 안에서 calc_parity 이라는 함수명에 ^address를 대입해준 것 입니다.
'EE > Verilog HDL' 카테고리의 다른 글
[verilog HDL] Syntax 5. Behavioral/Algorithmic Level Design (0) | 2022.02.27 |
---|---|
[verilog HDL] 16-bit ALU(Arithmetic Logic Unit) (0) | 2022.02.23 |
[verilog HDL] Syntax 3. Port (0) | 2022.02.22 |
[verilog HDL] Syntax 2. Data types (0) | 2022.02.22 |
[verilog HDL] MUX & DEMUX 여러 방법으로 구현하기 (0) | 2022.02.21 |